我可以在没有动态 sql 的情况下使用一个查询查询所有数据库中的存储过程吗

Jus*_*ing 6 sql-server stored-procedures

如果我想查询服务器上的所有数据库以查看是否存在存储过程,我可以组合sp_executesql并在类似于以下的查询上运行游标:

SELECT 
     'select ' + '''' + name + '''' + ', name from [' + name 
   + '].sys.procedures WHERE name = ''usp_MyProc'' COLLATE SQL_Latin1_General_CP1_CI_AI ' 
FROM sys.databases 
-- I get a collation error from the following
WHERE name NOT IN ('ReportServer', 'ReportServerTempDb');
Run Code Online (Sandbox Code Playgroud)

我可以在没有动态 sql 和游标的情况下做同样的事情吗?

Aar*_*and 7

您可以在没有光标的情况下(或没有类似光标的操作)进行操作。例如,您可以像这样稍微不同地执行此操作:

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';

SELECT @sql = @sql + CHAR(13) + CHAR(10)
  + N'select ''' + db.name + ''', p.name 
        from ' + QUOTENAME(db.name) + N'.sys.procedures AS p 
        WHERE p.name = N''usp_MyProc'' 
        COLLATE SQL_Latin1_General_CP1_CI_AI;' 
    FROM sys.databases AS db -- WHERE ...;

EXEC sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)

您还可以通过执行以下操作避免返回多个结果集:

CREATE TABLE #x(d SYSNAME, n SYSNAME);

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';

SELECT @sql = @sql + CHAR(13) + CHAR(10)
  + N'insert #x select ''' + db.name + ''', p.name 
        FROM ' + QUOTENAME(db.name) + N'.sys.procedures AS p
        WHERE p.name = N''usp_MyProc'' 
        COLLATE SQL_Latin1_General_CP1_CI_AI;' 
    FROM sys.databases AS db -- WHERE ...;

EXEC sp_executesql @sql;

SELECT d, n FROM #x ORDER BY d, n;
Run Code Online (Sandbox Code Playgroud)

不过,如果您真的只需要一个特定的存储过程,请参阅Martin 的回答


Eri*_*ins 4

您可以使用未记录的存储过程sp_msforeachdb

这里有一篇文章适合您:SQL Server 无文档存储过程 sp_MSforeachtable 和 sp_MSforeachdb,作者:Gregory A. Larsen。

但您还应该阅读: