如何列出 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 |
+----+-----------------------+-------+--------------------+----------+
P.S.
您可能希望通过编写连接到数据库的代码(例如在 Python 中)来自动化该过程,选择一个查询,获取其执行计划并将其保存到 table.
您可以使用 sp_describe_first_result_set
或 sys.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
对于查询中使用的每个引用的列表,您可以使用 sys.dm_sql_referenced_entities
。不过它只适用于存储过程。
我需要列出 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 |
+----+-----------------------+-------+--------------------+----------+
P.S.
您可能希望通过编写连接到数据库的代码(例如在 Python 中)来自动化该过程,选择一个查询,获取其执行计划并将其保存到 table.
您可以使用 sp_describe_first_result_set
或 sys.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
对于查询中使用的每个引用的列表,您可以使用 sys.dm_sql_referenced_entities
。不过它只适用于存储过程。