Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment puis-je obtenir une liste de toutes les colonnes référencées dans une procédure stockée ?

Lorsqu'une procédure stockée est exécutée, elle est analysée et compilée dans un plan de requête, celui-ci est mis en cache et vous pouvez y accéder via sys.dm_exec_cached_plans et sys.dm_exec_query_plan au format XML. Le plan de requête enregistre la "liste de sortie" de chaque section du code analysé. Pour voir quelles colonnes sont utilisées par la procédure stockée, il suffit d'interroger ce XML, comme ceci :

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

Mise en garde cela dépend de la façon dont vous définissez "utilisé". Il se peut qu'un CTE dans votre procédure stockée fasse référence à 5 colonnes d'une table, mais lorsque ce CTE est utilisé, seules trois des colonnes sont transmises. L'optimiseur de requête peut ignorez ces champs supplémentaires et ne les incluez pas dans le plan. D'un autre côté, l'optimiseur peut décider qu'il peut faire une requête plus efficace en incluant des champs supplémentaires dans une sortie pour lui permettre d'utiliser un meilleur index plus tard. Ce code renverra les colonnes utilisées par le plan de requête, il se peut qu'il ne s'agisse pas exactement des colonnes qui se trouvent dans le code de la procédure stockée.