循环遍历所有 SSMS 数据库而不重新创建存储过程

Loop Through All SSMS Databases without Recreating Stored Procedure

背景资料:

在Python中,如果我想对列表中的不同值应用相同的逻辑,我可能会写这样的东西。

database_list = ["db_1", "db_2", "db_3"]

for x in range(0,len(database_list),1):
     
     print("the database name is " + database_list[x])

我想做什么:

我想在 SSMS 中做的是为每个数据库提取一个数据库对象列表。我创建了一个存储过程来提取我想要的内容,但我必须针对每个数据库 运行 它,因此 10 个数据库意味着 运行 将其调用 10 次。

我的目标是使用 T-SQL 查询而不是 Python。

我试过这样做:

 exec sp_MSforeachdb 'USE ?; EXEC [dbo].[my_stored_procedure]';

问题是,[dbo].[my_stored_procedure] 必须存在于我要在其中执行此操作的每个数据库中。

如何在 1 个数据库中创建存储过程,然后对所有数据库或我选择的数据库列表执行它?

在 Master 数据库中创建带有 sp_ 前缀的存储过程,并在存储过程中使用动态 SQL 以便它解析相对于当前数据库的对象名称,而不是包含存储过程。

EG

use master 
go
CREATE OR ALTER  PROCEDURE [dbo].[sp_getobjects]
AS
exec ('
     select *
     from [sys].[objects]
     where is_ms_shipped = 0
     order by type, name
     ')
go

use AdventureWorks2017
exec sp_getobjects 

我知道你想做什么,如果这是我的想法(你似乎不愿意说出来!)你可以做以下事情:

master 数据库中,创建您的过程。通常你不会这样做,但在这种情况下你必须在它前面加上 sp_

use master
go
create procedure sp_testproc as

select top 10 * from sys.tables
go

现在,如果您 运行 这个,它将 return 来自 master 数据库的表。

如果您将上下文切换到另一个数据库并且 exec master.dbo.sp_testproc,它仍然会从 master 数据库中 return 个表。

master、运行

sys.sp_MS_marksystemobject sp_testproc

现在将上下文切换到不同的数据库并且exec master.dbo.sp_testproc

它将 return 来自您正在使用的数据库的表格。

尝试在 master 中创建存储过程并使用 sp_ 前缀命名:

USE master
GO

CREATE PROCEDURE sp_sproc_name
AS
 BEGIN
 ...
 END
GO

-- You *may* need to mark it as a system object
EXEC sys.sp_MS_marksystemobject sp_sprocname

参见:https://nickstips.wordpress.com/2010/10/18/sql-making-a-stored-procedure-available-to-all-databases/

它应该在所有数据库中可用

@LunchBox - 这是您的单个存储过程(您在一个数据库中创建的)实际上需要包含“exec sp_MSforeach ....”命令,而不是命令被执行为“EXEC”,它需要是您要放入存储过程中的实际 SQL。

例如。 (在您的单个存储过程中)

EXEC sp_MSforeachdb 'USE ?; SELECT * FROM <table>; UPDATE <another table> SET ...';

将存储过程(您放入一个数据库中的)视为与您的 Python 代码文件没有什么不同 - 如果您实际上想在 Python 中实现相同的事情,您要么需要在每个数据库中创建存储过程,要么在 Python 中构建 SQL 语句字符串并针对每个数据库执行它。

我理解您认为使用 SQL 可以实现的目标,但存储过程确实无法按您预期的方式工作。即使您处于不同数据库的上下文中,但您 运行 EXEC .stored_proc,该存储过程最终在 运行ning 的上下文中它所在的数据库(不是您的上下文数据库)。

现在,您可能遇到的唯一一个问题是标准 sp_MSforeachdb 存储过程对可以执行的命令有 2000 个字符的限制(尽管它确实有多个“命令" 参数,如果您计划 运行 一个非常大的代码块,这可能不切实际,可能带有贯穿始终的变量)。如果这可能会影响您打算做的事情,您可以在线搜索“sp_MSforeachdb alternatives”——人们似乎已经创建了一些命令参数可以包含更大的字符串.