sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cómo puedo obtener una lista de todas las columnas a las que se hace referencia en un procedimiento almacenado?

Cuando se ejecuta un procedimiento almacenado, se analiza y compila en un plan de consulta, se almacena en caché y puede acceder a él a través de sys.dm_exec_cached_plans y sys.dm_exec_query_plan en formato XML. El plan de consulta registra la 'lista de salida' de cada sección del código analizado. Ver qué columnas usa el procedimiento almacenado es solo cuestión de consultar este XML, así:

--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')

Advertencia emptor esto depende de cómo defina 'usado'. Puede ser que un CTE dentro de su procedimiento almacenado haga referencia a 5 columnas de una tabla, pero luego, cuando se usa este CTE, solo se pasan tres de las columnas. El optimizador de consultas puede ignore estos campos adicionales y no los incluya en el plan. Por otro lado, el optimizador puede decidir que puede hacer una consulta más eficiente al incluir campos adicionales en una salida para permitirle usar un mejor índice más adelante. Este código devolverá las columnas utilizadas por el plan de consulta, es posible que no sean exactamente las columnas que se encuentran en el código del procedimiento almacenado.