.net – 从查询中获取表模式
根据
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时,它提供联系而不是别名c.有没有办法从上面的查询中获取表模式和别名? 任何帮助都会很棒! 编辑 虽然我可以使用Rob建议的执行计划,但我会欣赏任何其他简单的方法. 通过tomekszpakowicz回答问题
我不是查询的作者.我们有一个用户可以输入查询的系统.我们使用上面解释的方法从中构建列.这些细节将被保留,另一个用户可以使用它来添加新标准等.因此我们需要根据我们的信息动态构建SQL.因此,当列具有别名并且我们没有获得别名时,则构造的where子句将无效. 谢谢 解决方法简短的回答这不行.根据设计,您无法从结果模式中获取表别名.而且你不能依赖于能够从查询执行计划中获取它们. 答案很长 当您获得SQL查询的结果时,该查询已经被解析,验证,优化,编译成一些内部表示并执行.别名是查询的“源代码”的一部分,通常在步骤1和2的某处丢失. 在执行查询之后,唯一可以看作表的东西是a)真实的物理表和b)返回的数据看作单个匿名表.两者之间的所有内容都可以进行转换或完全优化. 如果要求DBMS保留别名,则实际上不可能优化复杂查询. 可能的解决方案 我建议重述一个问题: >您(或您的应用程序)是否有问题的查询来源?在这种情况下,您应该知道别名. >在最坏的情况下,您必须自己解析查询. 简单而丑陋的解决方案 如果我正确理解您的要求: >用户A在您的程序中输入查询. 在这种情况下: >当编辑查询时,尝试运行它并收集返回列的元数据. >检查过滤器列是否仍然有效(A可能已更改查询). select * from ({query entered by A}) x where x.Column1 op1 Value1 and x.Column2 op2 Value2 如果要优雅地处理数据库架构更改,则需要添加一些额外的检查以确保元数据与实际返回的查询一致. 安全说明 您的程序将直接将用户A写入的查询传递给数据库. 推论 如果用户A出于安全原因无法直接访问数据库,则无法使用上述解决方案. 在这种情况下,确保其安全的唯一方法是确保您的应用程序理解100%的查询,这意味着在程序中解析它并仅允许您认为安全的操作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |