在我的应用程序中,我得到了查询,我需要以编程方式附加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时,它提供联系而不是别名c.有没有办法从上面的查询中获取表模式和别名?
任何帮助都会很棒!
编辑
虽然我可以使用Rob建议的执行计划,但我会欣赏任何其他简单的方法.
通过tomekszpakowicz回答问题
Are you (or your application) source
of the query in question? In that case
you should know the aliases.
我不是查询的作者.我们有一个用户可以输入查询的系统.我们使用上面解释的方法从中构建列.这些细节将被保留,另一个用户可以使用它来添加新标准等.因此我们需要根据我们的信息动态构建sql.因此,当列具有别名并且我们没有获得别名时,则构造的where子句将无效.
谢谢
解决方法
这不行.根据设计,您无法从结果模式中获取表别名.而且你不能依赖于能够从查询执行计划中获取它们.
答案很长
当您获得SQL查询的结果时,该查询已经被解析,验证,优化,编译成一些内部表示并执行.别名是查询的“源代码”的一部分,通常在步骤1和2的某处丢失.
在执行查询之后,唯一可以看作表的东西是a)真实的物理表和b)返回的数据看作单个匿名表.两者之间的所有内容都可以进行转换或完全优化.
如果要求DBMS保留别名,则实际上不可能优化复杂查询.
可能的解决方案
我建议重述一个问题:
>您(或您的应用程序)是否有问题的查询来源?在这种情况下,您应该知道别名.
>如果你得到别人提供的查询……那么……这取决于你为什么要添加原因.
>在最坏的情况下,您必须自己解析查询.
>在最好的情况下,您可以授予他们访问视图而不是真实表的权限,并在视图中放置where子句.
简单而丑陋的解决方案
如果我正确理解您的要求:
>用户A在您的程序中输入查询.
>用户B可以运行它(但不能编辑它)并查看返回的数据.
此外,她可以使用您提供的某种窗口小部件根据返回的列添加过滤器.
>您不希望在应用程序中应用过滤器,而是将它们添加到查询中,以避免从数据库中获取不必要的数据.
在这种情况下:
>当编辑查询时,尝试运行它并收集返回列的元数据.
如果ColumnNames不是唯一的,请向作者投诉.
使用查询存储元数据.
>当B添加过滤器(基于查询元数据)时,存储两个列名称
和条件.
>执行时:
>检查过滤器列是否仍然有效(A可能已更改查询).
如果没有删除无效过滤器和/或通知B.
>执行查询,如:
select * from ({query entered by A}) x where x.Column1 op1 Value1 and x.Column2 op2 Value2
如果要优雅地处理数据库架构更改,则需要添加一些额外的检查以确保元数据与实际返回的查询一致.
安全说明
您的程序将直接将用户A写入的查询传递给数据库.
使用具有不超过A的数据库权限的权限的数据库连接来执行此操作至关重要.
否则,您要求基于sql注入的漏洞利用.
推论
如果用户A出于安全原因无法直接访问数据库,则无法使用上述解决方案.
在这种情况下,确保其安全的唯一方法是确保您的应用程序理解100%的查询,这意味着在程序中解析它并仅允许您认为安全的操作.