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

Lister toutes les colonnes référencées dans toutes les procédures de toutes les bases de données

Cela obtiendra la liste que vous recherchez, mais cela ne vous aidera pas si vous avez de telles références de colonne intégrées dans du SQL dynamique (et ne pouvez pas trouver de références qui reposent sur une résolution de nom différée). SQL Server n'analyse pas le texte de la procédure stockée pour obtenir la sortie DMV.

Essayez maintenant avec COLLATE clauses pour traiter les cas où vous avez des bases de données sur le même serveur avec des classements différents.

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;

Aussi le CROSS APPLY La syntaxe ne fonctionnera pas si vous avez des bases de données en mode de compatibilité 80. Assurez-vous simplement de ne pas exécuter le code dans une telle base de données et cela devrait fonctionner correctement (même si certaines des bases de données cibles sont en 80).