【问题标题】:Get fields used within SQL query获取 SQL 查询中使用的字段
【发布时间】:2020-02-26 16:33:59
【问题描述】:

我希望能够返回给定 SQL 查询使用的所有字段的列表(最好包含表详细信息)。例如。查询的输入:

SELECT t1.field1, field3
FROM dbo.table1 AS t1
INNER JOIN dbo.table2 as t2
    ON t2.field2 = t1.field2
WHERE t2.field1 = 'someValue'

会回来

+--------+-----------+--------+
| schema | tablename | field  |
+--------+-----------+--------+
| dbo    | table1    | field1 |
| dbo    | table1    | field2 |
| dbo    | table1    | field3 |
| dbo    | table2    | field1 |
| dbo    | table2    | field2 |
+--------+-----------+--------+

真的需要使用 SQL 内核(这个词对吗?引擎?)因为读者无法知道 field3 在 table1 而不是 table2 中。出于这个原因,我假设解决方案是 SQL。如果它也可以处理SELECT *,则可以加分!

我尝试了一个使用 sqlparse (https://sqlparse.readthedocs.io/en/latest/) 的 python 解决方案,但是在处理涉及临时表、子查询和 CTE 的更复杂的 SQL 查询时遇到了麻烦。别名的处理也非常困难(特别是如果查询在多个地方使用相同的别名)。显然它不能处理像上面的field3 这样没有表标识符的情况。也不能处理SELECT *

我希望 SQL Server Management Studio 中可能有更优雅的解决方案,甚至 SQL Server 本身中的某些功能。我们有来自 Redgate 的 SQL Prompt,它在智能感知中必须对架构和格式化的 SQL 查询有一定的了解。

更新: 根据要求:我尝试这样做的原因是确定哪些Users 可以在我们的组织内执行哪些 SSRS 报告。这完全取决于他们将GRANT SELECT 权限分配给他们的Roles 对给定报告中所有数据集(在我们的例子中是SQL 查询)使用的所有字段。我已经设法根据Roles 报告哪些UsersGRANT SELECT 在哪些字段上。我现在想扩展那些权限允许它们运行的​​报告。

【问题讨论】:

  • Redgate 用 SQL Prompt 有效地编写了自己的智能感知,而这些事情并不简单;它是一个与 SSMS(和预览版中的 ADS)集成的完整应用程序。您实际上是在问“我如何对 T-SQL 进行逆向工程?”或“谁能给我写一个应用程序来反向引擎一组 T-SQL 批处理”。这个问题太宽泛了。充其量,您需要编写自己的应用程序来执行此操作,当您遇到困难时,发布您拥有的代码,解释它为什么不起作用,并告诉我们您的预期结果。
  • 为什么需要这种信息,尤其是这样的格式?什么目的?也许如果您分享您需要解决的问题,我们也许可以提供答案。 Redgate 的 SQL 提示正在使用来自系统信息架构视图 (INFORMATION_SCHEMA) 和其他系统表的数据。

标签: python sql sql-server sql-parser


【解决方案1】:

列表名称可能很棘手,因为列名称可能不明确甚至派生。但是,您几乎可以从任何查询或存储过程中获取列名、序列和类型。

示例

Select column_ordinal
      ,name
      ,system_type_name 
  From sys.dm_exec_describe_first_result_set('Select * from YourTable',null,null )  

【讨论】:

    【解决方案2】:

    我想我现在找到了答案。请注意:我目前没有执行这些功能的权限,所以我还没有测试它——当我有机会测试它时,我会更新答案。感谢@milivojeviCH 的回答。答案从这里复制:https://stackoverflow.com/a/19852614/6709902

    选择 SQL Server 执行计划中使用的所有列的最终目标已解决:

    USE AdventureWorksDW2012
    
    DBCC FREEPROCCACHE
    
    SELECT dC.Gender, dc.HouseOwnerFlag, 
    SUM(fIS.SalesAmount) AS SalesAmount 
    FROM 
        dbo.DimCustomer dC INNER JOIN
        dbo.FactInternetSales fIS ON fIS.CustomerKey = dC.CustomerKey 
    GROUP BY dC.Gender, dc.HouseOwnerFlag
    ORDER BY dC.Gender, dc.HouseOwnerFlag
    /*
    query_hash          query_plan_hash
    0x752B3F80E2DB426A  0xA15453A5C2D43765
    */
    
    DECLARE @MyQ AS XML;
    
    -- SELECT qstats.query_hash, query_plan_hash, qplan.query_plan AS [Query Plan],qtext.text 
    SELECT @MyQ = qplan.query_plan 
     FROM sys.dm_exec_query_stats AS qstats 
      CROSS APPLY sys.dm_exec_query_plan(qstats.plan_handle) AS qplan 
      cross apply sys.dm_exec_sql_text(qstats.plan_handle) as qtext 
      where text like '% fIS %'
    and query_plan_hash = 0xA15453A5C2D43765
    
    SeLeCt @MyQ
    
    ;WITH xmlnamespaces (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
    SELECT DISTINCT
        [Database] = x.value('(@Database)[1]', 'varchar(128)'),
        [Schema]   = x.value('(@Schema)[1]',   'varchar(128)'),
        [Table]    = x.value('(@Table)[1]',    'varchar(128)'),
        [Alias]    = x.value('(@Alias)[1]',    'varchar(128)'),
        [Column]   = x.value('(@Column)[1]',   'varchar(128)')
    FROM   @MyQ.nodes('//ColumnReference') x1(x)
    

    导致以下输出:

    Database                  Schema Table            Alias Column
    ------------------------- ------ ---------------- ----- ----------------
    NULL                      NULL   NULL             NULL  Expr1004
    [AdventureWorksDW2012]    [dbo]  [DimCustomer]    [dC]  CustomerKey
    [AdventureWorksDW2012]    [dbo]  [DimCustomer]    [dC]  Gender
    [AdventureWorksDW2012]    [dbo]  [DimCustomer]    [dC]  HouseOwnerFlag
    [AdventureWorksDW2012]    [dbo]  [FactInternetSal [fIS] CustomerKey
    [AdventureWorksDW2012]    [dbo]  [FactInternetSal [fIS] SalesAmount
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-27
      • 2014-12-03
      相关资源
      最近更新 更多