更新多个数据库上的存储过程

alp*_*pha 8 sql-server

我们为每位客户提供单独的数据库.它们都具有相同的表和存储过程.问题是当我们必须更新存储过程时,我们必须确保为所有数据库更新它.当然,数据库上的一个存储过程可能会被忽略而不会更新.

我已经考虑过创建一个存储过程master并使用它作为前缀,sp_并设置将对象标记为系统对象sys.sp_MS_marksystemobject.这似乎工作....但是,这文章说," 不建议使用此解决方案专为实时的数据库服务器,你可以用它在开发和测试服务器,以加快开发和测试."

如果是这样的话,什么是生产的最佳解决方案?

Eil*_*eth 8

如果目标基本上只是将存储过程部署到每个客户端数据库,那么像这样的脚本应该可以工作.

-- 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
Run Code Online (Sandbox Code Playgroud)

您可以通过从sys.sql_modules中提取过程定义来做一些漂亮的事情,但是在执行CREATE vs. ALTER时可能会遇到一些复杂问题.