List all columns referenced in all procedures of all databases

后端 未结 3 1924
花落未央
花落未央 2021-01-15 06:20

Is there a way that I can get all the columns and tables referenced in all the stored procedures in all the databases in an instance? The output should be:



        
3条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-15 07:01

    This will get the list you're after, however it won't help you if you have such column references embedded in dynamic SQL (and may not find references that rely on deferred name resolution). SQL Server doesn't parse the text of the stored procedure to come up with the DMV output.

    Try now with COLLATE clauses to deal with cases where you have databases on the same server with different collations.

    DECLARE @sql NVARCHAR(MAX) = N'';
    
    SELECT @sql += N'UNION ALL
    SELECT 
      [database]  = ''' + REPLACE(name, '''', '''''') + ''',
      [procedure] = QUOTENAME(s.name) + ''.'' + QUOTENAME(p.name)
                    COLLATE Latin1_General_CI_AI, 
      [table]     = QUOTENAME(referenced_schema_name) + ''.'' 
                  + QUOTENAME(referenced_entity_name)
                    COLLATE Latin1_General_CI_AI,
      [column]    = QUOTENAME(referenced_minor_name)
                    COLLATE Latin1_General_CI_AI
    FROM ' + QUOTENAME(name) + '.sys.schemas AS s
    INNER JOIN ' + QUOTENAME(name) + '.sys.procedures AS p
    ON s.[schema_id] = p.[schema_id]
    CROSS APPLY ' + QUOTENAME(name) 
    + '.sys.dm_sql_referenced_entities'
    + '(QUOTENAME(s.name) + ''.'' + QUOTENAME(p.name), N''OBJECT'') AS d
    WHERE d.referenced_minor_id > 0'
    FROM sys.databases 
      WHERE database_id > 4 
      AND [state] = 0;
    
    SET @sql = STUFF(@sql,1,11,'');
    
    EXEC sp_executesql @sql;
    

    Also the CROSS APPLY syntax won't work if you have databases that are in 80 compatibility mode. Just make sure you don't execute the code in such a database and it should work fine (even if some of the target databases are in 80).

提交回复
热议问题