Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie kann ich eine Liste aller Spalten abrufen, auf die in einer gespeicherten Prozedur verwiesen wird?

Wenn eine gespeicherte Prozedur ausgeführt wird, wird sie analysiert und in einen Abfrageplan kompiliert, dieser zwischengespeichert und Sie können darauf über sys.dm_exec_cached_plans und sys.dm_exec_query_plan im XML-Format zugreifen. Der Abfrageplan zeichnet die „Ausgabeliste“ jedes Abschnitts des geparsten Codes auf. Um zu sehen, welche Spalten von der gespeicherten Prozedur verwendet werden, müssen Sie nur dieses XML wie folgt abfragen:

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

Einschränkungsvorbehalt das hängt davon ab, wie Sie "gebraucht" definieren. Es kann sein, dass ein CTE innerhalb Ihrer Stored Procedure auf 5 Spalten einer Tabelle verweist, aber dann werden bei Verwendung dieses CTE nur drei der Spalten weitergegeben. Der Abfrageoptimierer kann Ignorieren Sie diese zusätzlichen Felder und nehmen Sie sie nicht in den Plan auf. Auf der anderen Seite kann der Optimierer entscheiden, dass er eine effizientere Abfrage durchführen kann, indem er zusätzliche Felder in eine Ausgabe einbezieht, damit er später einen besseren Index verwenden kann. Dieser Code gibt die vom Abfrageplan verwendeten Spalten zurück, sie sind möglicherweise nicht genau die Spalten, die sich im Code der gespeicherten Prozedur befinden.