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