As per MSDN, SqlDataReader.GetSchemaTable
返回所执行查询的列元数据。我想知道是否有类似的方法可以为给定的查询提供表元数据?我的意思是涉及哪些表以及它有哪些别名。
在我的应用程序中,我收到查询,并且需要附加where
以编程方式子句。使用GetSchemaTable()
,我可以获得列元数据及其所属的表。但即使表有别名,它仍然返回真实的表名。有没有办法获取该表的别名?
以下代码显示获取列元数据。
const string connectionString = "your_connection_string";
string sql = "select c.id as s,c.firstname from contact as c";
using(SqlConnection connection = new SqlConnection(connectionString))
using(SqlCommand command = new SqlCommand(sql, connection))
{
connection.Open();
SqlDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo);
DataTable schema = reader.GetSchemaTable();
foreach (DataRow row in schema.Rows)
{
foreach (DataColumn column in schema.Columns)
{
Console.WriteLine(column.ColumnName + " = " + row[column]);
}
Console.WriteLine("----------------------------------------");
}
Console.Read();
}
这将正确地为我提供列的详细信息。但当我看到BaseTableName
对于列Id
,它正在给予contact
而不是别名c
。有什么方法可以从上面这样的查询中获取表架构和别名吗?
任何帮助都会很棒!
Edit
虽然我可以使用 Rob 建议的执行计划,但我很感激任何替代的简单方法。
回答 Tomekszpakowicz 的问题
您(或您的应用程序)是来源吗
有问题的查询?在这种情况下
你应该知道别名。
我不是查询的作者。我们有一个系统,用户可以在其中输入查询。我们使用我上面解释的方法从中构建列。这些详细信息将被保留,其他用户可以使用它,例如添加新条件等。因此,我们需要根据我们拥有的信息动态构建 SQL。因此,当列有别名并且我们没有获取别名时,构造的 where 子句将无效。
Thanks
简短回答
这行不通。根据设计,您无法从结果模式中获取表别名。并且您不能依赖能够从查询执行计划中获取它们。
长答案
当您获得 SQL 查询的结果时,该查询已经被解析、验证、优化、编译成某种内部表示并执行。别名是查询“源代码”的一部分,通常会在步骤 1 和 2 附近的某个地方丢失。
执行查询后,唯一可以被视为表的东西是a)真实的物理表和b)被视为单个匿名表的返回数据。两者之间的一切都可以转变或完全优化。
如果 DBMS 需要保留别名,那么优化复杂查询实际上是不可能的。
可能的解决方案
我建议重述一个问题:
您(或您的应用程序)是相关查询的来源吗?在这种情况下,您应该知道别名。
-
如果您收到其他人提供的查询...那么...这取决于您为什么添加原因。
简单而丑陋的解决方案
如果我正确理解您的要求:
在这种情况下:
如果您想优雅地处理数据库架构更改,您需要添加一些额外的检查以确保元数据与查询实际返回的内容一致。
安全说明
您的程序将把用户 A 编写的查询直接传递到数据库。
至关重要的是,您使用数据库连接来执行此操作的权限不超过 A 的数据库权限。
否则,您将要求基于 SQL 注入的漏洞利用。
推论
如果出于安全原因用户 A 无权直接访问数据库,则不能使用上述解决方案。
在这种情况下,确保其安全的唯一方法是确保您的应用程序理解 100% 的查询,这意味着在您的程序中解析查询并仅允许您认为安全的操作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)