Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come posso ottenere un elenco di tutte le colonne a cui si fa riferimento in una stored procedure?

Quando una procedura memorizzata viene eseguita, viene analizzata e compilata in un piano di query, questo viene memorizzato nella cache ed è possibile accedervi tramite sys.dm_exec_cached_plans e sys.dm_exec_query_plan in formato XML. Il piano di query registra l'"elenco di output" di ciascuna sezione del codice analizzato. Vedere quali colonne sono utilizzate dalla procedura memorizzata è solo questione di interrogare questo XML, in questo modo:

--Execute the stored procedure to put its query plan in the cache
exec sys.sp_columns ''

DECLARE @TargetObject nvarchar(100) = 'sys.sp_columns';

WITH XMLNAMESPACES (
    'http://schemas.microsoft.com/sqlserver/2004/07/showplan' as ns1
), CompiledPlan AS (
    SELECT 
        (SELECT query_plan FROM sys.dm_exec_query_plan(cp.plan_handle)) qp,
        (SELECT ObjectID FROM sys.dm_exec_sql_text(cp.plan_handle)) ob
    FROM sys.dm_exec_cached_plans cp
    WHERE objtype = 'Proc'
), ColumnReferences AS (
    SELECT DISTINCT
        ob,
        p.query('.').value('./ns1:ColumnReference[1]/@Database', 'sysname') AS [Database],
        p.query('.').value('./ns1:ColumnReference[1]/@Schema', 'sysname') AS [Schema],
        p.query('.').value('./ns1:ColumnReference[1]/@Table', 'sysname') AS [Table],
        p.query('.').value('./ns1:ColumnReference[1]/@Column', 'sysname') AS [Column]
    FROM CompiledPlan
        CROSS APPLY qp.nodes('//ns1:ColumnReference') t(p)
)

SELECT 
    [Database], 
    [Schema], 
    [Table], 
    [Column]
FROM ColumnReferences 
WHERE 
    [Database] IS NOT NULL AND 
    ob = OBJECT_ID(@TargetObject, 'P')

Caveat emptor questo dipende da come definisci 'usato'. È possibile che un CTE all'interno della procedura memorizzata faccia riferimento a 5 colonne da una tabella, ma quando viene utilizzato questo CTE vengono trasmesse solo tre colonne. Query Optimizer potrebbe ignora questi campi extra e non includerli nel piano. D'altra parte, l'ottimizzatore può decidere di eseguire una query più efficiente includendo campi aggiuntivi in ​​un output per consentirgli di utilizzare un indice migliore in seguito. Questo codice restituirà le colonne utilizzate dal piano di query, potrebbero non essere esattamente le colonne che si trovano nel codice della stored procedure.