我的最终目标是从缓存的执行计划中自动提取所有引用的列。这将有助于我们跟踪预定的SSRS报告集使用的所有列。
感兴趣的XML数据如下:
<ColumnReference Database="[AdventureWorksDW2012]" Schema="[dbo]" Table="[DimCustomer]" Alias="[dC]" Column="HouseOwnerFlag" />
而且我想将数据库,模式,表,别名和列值存储在表中。
但是,为了进行概念验证,我进行了一个简单的查询,并将完整执行计划的以下部分复制到下面的TSQL代码中:
DECLARE @myDoc xml;
SET @myDoc = '<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.2" Build="11.0.3381.0" TEST="1">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementText="SELECT ... 
" StatementId="1" StatementCompId="1" ThereIsMoreHere="..." >
<StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" ThereIsMoreHere="..." />
</StmtSimple>
</Statements>
</Batch>
</BatchSequence>
</ShowPlanXML>';
SELECT StatementId = @myDoc.value('(/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple/@StatementId)[1]', 'int');
SELECT StatementId = @myDoc.value('(/ShowPlanXML/@TEST)[1]', 'int');
两个SELECT语句都返回NULL。怎么了我觉得我正在慢慢失明。这是针对SQL Server 2012 SP1开发人员版执行的。
您需要为xml指定架构和默认名称空间:-
with xmlnamespaces (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT StatementId = @myDoc.value('(/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple/@StatementId)[1]', 'int');
with xmlnamespaces (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT StatementId = @myDoc.value('(/ShowPlanXML/@TEST)[1]', 'int');
选择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
@ milivojevich,如果我想从多个元素中获取数据怎么办?