![]() |
1
11
简短回答 这行不通。根据设计,不能从结果架构中获取表别名。并且您不能依赖于能够从查询执行计划中获取它们。 长回答 当您得到SQL查询的结果时,查询已经被分析、验证、优化、编译成一些内部表示并执行。别名是查询“源代码”的一部分,通常会在步骤1和2左右丢失。 执行查询后,只能将a)实际物理表和b)返回的数据视为单个匿名表。两者之间的一切都可以转化或完全优化。 如果需要DBMS来保留别名,那么实际上就不可能优化复杂的查询。 可能的解决方案 我建议重述一个问题:
简单而难看的解决方案 如果我正确理解您的要求:
在这种情况下:
如果要优雅地处理数据库模式更改,则需要添加一些附加检查,以确保元数据与查询实际返回的内容一致。 安全票据 您的程序将把用户编写的查询直接传递到数据库。 使用具有不超过A的数据库权限的数据库连接来完成此操作是至关重要的。 否则,您将要求使用基于SQL注入的漏洞。 推论 如果出于安全原因,用户A不能直接访问数据库,则不能使用上述解决方案。 在这种情况下,确保安全的唯一方法是确保应用程序100%理解查询,这意味着在程序中解析查询,并且只允许您认为安全的操作。 |
![]() |
2
4
您可以获取查询的执行计划,然后分析返回的XML。这类似于在ManagementStudio中使用“显示估计计划”选项。 |
![]() |
3
2
您几乎需要一个解析器来解析SQL,然后从解析的查询中生成一个包含别名及其引用的表的符号表。然后将其与getSchemaTable()的结果结合起来,以便将列映射到适当的别名。 不管怎样,看看这个问题 Parsing SQL code in C# 对于一些解析器。我没有详细看过,但也许其中一个就是你需要的。如果只执行select语句,请检查antlr链接和的语法 http://www.antlr.org/grammar/1062280680642/MS_SQL_SELECT.html . 如果查询很简单,则可以使用正则表达式或自己的自定义语法从查询中解析别名和表名。这可能是最简单的解决方案。 最健壮的解决方案可能是为其他人的解析器付费,这些解析器处理完整的SQL,并将其分解成一个解析树,或者在其他地方查询它。我不确定每一个的优点和价格/稳健性比率。但其中一些是非常昂贵的……我想说,如果你不能自己去做,就去探索antlr语法(因为它是免费的),假设你只需要select语句。否则,您可能需要支付…… 实际上,假设您的用户不是疯狂的SQL天才,而是使用子查询等。我不明白为什么您不能使用模式视图中的表名,因为您说必须在查询中找到它们,然后将别名作为表名别名或表名作为别名。这可能适用于许多情况……但是对于完整的一般情况,您需要一个完整的解析器….. |
![]() |
4
0
我认为RobFarley的ShowPlanXML可以为您工作(假设您运行的SQL Server已经足够晚了,具有此功能)。
每列似乎都有
|
![]() |
5
0
实际上,你可以。请看我的答案: https://stackoverflow.com/a/19537164/88409
您需要做的是使用
为了更进一步,我必须推测这样的别名不能被优化,因为引擎必须使用它们来区分同一列与同一表的不同实例。
实际上,如果您运行这样的查询:
例如,如果运行类似“set showplan”的XML; 从功课A、功课B、功课C中选择*(从功课D中选择*)子查询\u别名\u不会像\u表\u别名那样粘贴\u` 您将得到如下输出:
|
![]() |
user6748530 · 将动态XML文件加载到树视图控件 7 年前 |
![]() |
Ishan Khare · Kotlin无法导入包 7 年前 |
![]() |
H4p7ic · 排序服务总线队列消息 7 年前 |
![]() |
user3026965 · 导出到时,在文件名中插入时间戳。csv 7 年前 |
![]() |
user2861089 · 从基因组gbff文件中提取元数据 7 年前 |