如何列出 SQL 查询中使用的所有列(包括架构和 table)

How to list all columns (including schema and table) used in a SQL query

我需要列出 SQL 查询中使用的所有列(包括模式和 table)。

我这样做的原因是因为我需要记录现有 Power BI 报告、存储过程和视图的候选清单正在使用的所有必需数据。然后,我正在进行差距分析,以查看新环境中已有哪些数据可用,并记录需要迁移哪些数据,以便能够重现候选名单中的报告、存储过程和视图。

输入

SELECT FullName, EmailAddress
FROM dbo.Customers t1
LEFT JOIN dbo.Customer_EmailAddress t2 ON t1.CustomerID = t2.CustomerID

输出应该是:

dbo.Customers.CustomerID
dbo.Customers.FirstName
dbo.Customer_EmailAddress.CustomerID
dbo.Customer_EmailAddress.EmailAddress

有谁知道这样做的方法吗?我需要为大量查询执行此操作,目前我手动执行此操作非常耗时!

试试下面的代码:

select sc.TABLE_SCHEMA + N'.' + o.name + N'.' + c.name  from sys.all_objects o 
inner join sys.all_columns c on o.object_id = c.object_id
inner join  INFORMATION_SCHEMA.TABLES sc on o.name = sc.TABLE_NAME
where type = N'U'

通过上述 SQL 服务器查询,您可以根据需要获取列列表:

dbo.Customers.CustomerID

然后您可以过滤 table 和列以达到您需要的列。

一旦你有一个查询,你可以得到一个XML格式的执行计划,例如通过使用以下代码。

SET SHOWPLAN_XML ON;  
GO

-- your query here

select ...

GO

SET SHOWPLAN_XML OFF;  
GO

执行计划包含 ColumnReference 元素,其中包含您需要的数据(数据库、架构、table 和列),例如:

<ColumnReference Database="[mydb]" Schema="[sys]" Table="[sysschobjs]" Alias="[o]" Column="id">

将你得到的XML插入table,例如

create table ExecutionPlan(id int primary key,execution_plan xml)

-- cannot insert the real XML here due to SO post length limitations
insert into ExecutionPlan values (1, '<ShowPlanXML ...');
insert into ExecutionPlan values (2, '<ShowPlanXML ...');
insert into ExecutionPlan values (3, '<ShowPlanXML ...');

完成插入后,使用以下查询提取列


with xmlnamespaces('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as ns)

select      distinct

            ep.id
           ,e.val.value ('@Database' ,'sysname')    as db 
           ,e.val.value ('@Schema'   ,'sysname')    as scm 
           ,e.val.value ('@Table'    ,'sysname')    as tab 
           ,e.val.value ('@Column'   ,'sysname')    as col 
                         
from        ExecutionPlan as ep
            cross apply execution_plan.nodes ('//ns:ColumnReference') as e (val)     

where       e.val.value ('@Database' ,'sysname') is not null

order by    id, db, scm, tab, col

+----+-----------------------+-------+--------------------+----------+
| id |          db           |  scm  |        tab         |   col    |
+----+-----------------------+-------+--------------------+----------+
|  1 | [mydb]                | [dbo] | [mytable]          | i        |
|  1 | [mydb]                | [dbo] | [mytable]          | v        |
|  2 | [mydb]                | [dbo] | [mytable]          | i        |
|  2 | [mydb]                | [dbo] | [mytable]          | v        |
|  3 | [mssqlsystemresource] | [sys] | [syspalnames]      | class    |
|  3 | [mssqlsystemresource] | [sys] | [syspalnames]      | name     |
|  3 | [mssqlsystemresource] | [sys] | [syspalnames]      | value    |
|  3 | [mssqlsystemresource] | [sys] | [syspalvalues]     | class    |
|  3 | [mssqlsystemresource] | [sys] | [syspalvalues]     | name     |
|  3 | [mssqlsystemresource] | [sys] | [syspalvalues]     | value    |
|  3 | [mydb]                | [sys] | [sysidxstats]      | id       |
|  3 | [mydb]                | [sys] | [sysidxstats]      | indid    |
|  3 | [mydb]                | [sys] | [sysidxstats]      | intprop  |
|  3 | [mydb]                | [sys] | [sysmultiobjrefs]  | class    |
|  3 | [mydb]                | [sys] | [sysmultiobjrefs]  | depid    |
|  3 | [mydb]                | [sys] | [sysobjvalues]     | objid    |
|  3 | [mydb]                | [sys] | [sysobjvalues]     | valclass |
|  3 | [mydb]                | [sys] | [sysobjvalues]     | valnum   |
|  3 | [mydb]                | [sys] | [sysobjvalues]     | value    |
|  3 | [mydb]                | [sys] | [sysschobjs]       | created  |
|  3 | [mydb]                | [sys] | [sysschobjs]       | id       |
|  3 | [mydb]                | [sys] | [sysschobjs]       | intprop  |
|  3 | [mydb]                | [sys] | [sysschobjs]       | modified |
|  3 | [mydb]                | [sys] | [sysschobjs]       | name     |
|  3 | [mydb]                | [sys] | [sysschobjs]       | nsclass  |
|  3 | [mydb]                | [sys] | [sysschobjs]       | nsid     |
|  3 | [mydb]                | [sys] | [sysschobjs]       | pclass   |
|  3 | [mydb]                | [sys] | [sysschobjs]       | pid      |
|  3 | [mydb]                | [sys] | [sysschobjs]       | status   |
|  3 | [mydb]                | [sys] | [sysschobjs]       | status2  |
|  3 | [mydb]                | [sys] | [sysschobjs]       | type     |
|  3 | [mydb]                | [sys] | [syssingleobjrefs] | class    |
|  3 | [mydb]                | [sys] | [syssingleobjrefs] | depid    |
|  3 | [mydb]                | [sys] | [syssingleobjrefs] | depsubid |
|  3 | [mydb]                | [sys] | [syssingleobjrefs] | indepid  |
+----+-----------------------+-------+--------------------+----------+

Fiddle

P.S.
您可能希望通过编写连接到数据库的代码(例如在 Python 中)来自动化该过程,选择一个查询,获取其执行计划并将其保存到 table.

您可以使用 sp_describe_first_result_setsys.dm_exec_describe_first_result_set

例如:

create table t(id int, v varchar(30))
select
  name as ActualColumnName,
  concat(
  QUOTENAME(s.source_database),
  '.',
  QUOTENAME(s.source_schema),
  '.',
  QUOTENAME(s.source_table),
  '.')
  + QUOTENAME(s.source_column) AS SourceName
from sys.dm_exec_describe_first_result_set(N'
SELECT id, v
FROM dbo.t
', N'', 1) s;

第二个参数是变量。例如:

select
  name as ActualColumnName,
  concat(
  QUOTENAME(s.source_database),
  '.',
  QUOTENAME(s.source_schema),
  '.',
  QUOTENAME(s.source_table),
  '.')
  + QUOTENAME(s.source_column) AS SourceName
from sys.dm_exec_describe_first_result_set(N'
SELECT id, v, @v
FROM dbo.t
', N'@v varchar(100)', 1) s

db<>fiddle

对于查询中使用的每个引用的列表,您可以使用 sys.dm_sql_referenced_entities。不过它只适用于存储过程。