Sql server 在多个数据库上更新存储过程
我们为每个客户都有一个单独的数据库。它们都有相同的表和存储过程。问题是,当我们必须更新存储过程时,我们必须确保为所有数据库更新存储过程。当然,数据库中的一个存储过程可能会被忽略而没有更新 我已经研究了在Sql server 在多个数据库上更新存储过程,sql-server,Sql Server,我们为每个客户都有一个单独的数据库。它们都有相同的表和存储过程。问题是,当我们必须更新存储过程时,我们必须确保为所有数据库更新存储过程。当然,数据库中的一个存储过程可能会被忽略而没有更新 我已经研究了在master中创建一个存储过程,并在其前面加上sp_u,还设置了使用sys.sp_MS_marksystemobject将对象标记为系统对象。这似乎有效。。。。但是,这表示“不建议将此解决方案用于实时数据库服务器,您可以在开发和测试服务器中使用它来加快开发和测试。” 如果是这样的话,生产环境中最好
master
中创建一个存储过程,并在其前面加上sp_u
,还设置了使用sys.sp_MS_marksystemobject
将对象标记为系统对象。这似乎有效。。。。但是,这表示“不建议将此解决方案用于实时数据库服务器,您可以在开发和测试服务器中使用它来加快开发和测试。”
如果是这样的话,生产环境中最好的解决方案是什么?如果目标基本上只是将存储过程部署到每个客户机数据库,那么类似于此脚本的东西应该可以工作
-- put the entire stored procedure code in a variable
-- have it start with "PROC" so we can easily either create or alter the
-- procedure based on whether it already exists or not
DECLARE @sp_code NVARCHAR(MAX) =
'
PROC [dbo].[usp_some_proc] AS
SELECT DB_NAME()
'
-- get a list of databases to install the stored procedure to
SELECT
[name]
INTO #tbl_databases
FROM sys.databases
WHERE [name] LIKE 'db[_]client[0-9]'
-- define some variables to use in the loop
DECLARE @sql NVARCHAR(MAX);
DECLARE @execute_sql NVARCHAR(MAX);
DECLARE @database_name NVARCHAR(500);
-- iterate through each database
WHILE EXISTS (SELECT * FROM #tbl_databases)
BEGIN
-- get this iteration's database
SELECT TOP 1
@database_name = [name]
FROM #tbl_databases
-- determine whether stored procedure should be created or altered
IF OBJECT_ID(QUOTENAME(@database_name) + '.[dbo].[usp_some_proc]') IS NULL
SET @sql = 'CREATE' + @sp_code;
ELSE
SET @sql = 'ALTER' + @sp_code;
-- define some dynamic sql to execute against the appropriate database
SET @execute_sql = 'EXEC ' + QUOTENAME(@database_name) + '.[dbo].[sp_executesql] @sql';
-- execute the code to create/alter the procedure
EXEC [dbo].[sp_executesql] @execute_sql, N'@sql NVARCHAR(MAX)', @sql;
-- delete this database so the loop will process the next one
DELETE FROM #tbl_databases
WHERE [name] = @database_name
END
-- clean up :)
DROP TABLE #tbl_databases
您可以通过从sys.sql_模块中提取过程定义来做一些巧妙的事情,但在执行CREATE vs.ALTER时可能会遇到一些复杂情况。为了补充Eilert的优秀答案,如果您从现有数据库复制项目,您可以获得对象文本的相关部分(在本例中为存储过程)执行以下操作:
DECLARE @RawDefinition NVARCHAR(max) =
OBJECT_DEFINITION (OBJECT_ID(N'[source_db].[dbo].[usp_some_proc]'))
SELECT PATINDEX('%PROCEDURE%', @RawDefinition)
DECLARE @sp_code NVARCHAR(max) = ' ' + Right(@RawDefinition, Len(@RawDefinition) -
PATINDEX('%PROCEDURE%', @RawDefinition) + 1)
你应该好好看看-这是一个很好的工具,可以同时将多个脚本部署到多个服务器(或数据库)上。这可以帮你省去很多麻烦!谢谢!这看起来是一个很好的解决方案。谢谢!我们有一些类似于你这里的东西。我认为红门解决方案可能会省去很多麻烦!