如何在多个数据库中运行存储过程

时间:2009-07-30 11:00:16

标签: sql-server-2005

在单个SQL Server实例中,我有以下数据库:

  • 总部
  • Branch001
  • Branch002
  • Branch003

...

  • NNN

在每个分支DB中都有一个名为usp_ComputeDailySales的过程,它执行一些计算并将每日销售数据写入Headquarters数据库。如何在Headquarters DB中编写单个存储过程以在所有分支DB中执行usp_ComputeDailySales

我可以写下面的代码,但我认为这不是可行的方法。

USE Branch001
EXEC usp_ComputeDailySales

USE Branch002
EXEC usp_ComputeDailySales

...

我想要一些方法同时为所有分支DB执行该过程。

4 个答案:

答案 0 :(得分:2)

这不是动态SQL,而是依赖于延迟名称解析等。

EXECUTE,请参阅@module_name_var参数

DECLARE @sql varchar(300)
SELECT
    [name] + '..usp_ComputeDailySales' AS Cmd
INTO #List
FROM
    sys.databases d WHERE d.[name] LIKE 'branch%'
    OR --Thanks Mitch
    d.[name] = 'Headquarters'

WHILE EXISTS (SELECT * FROM #List)
BEGIN
    SELECT TOP 1 @SQL = Cmd FROM #List
    EXEC @SQL
    DELETE #List WHERE Cmd = @SQL
END

在KM的评论之后编辑

是的,有区别但我会澄清:

EXEC(@SQL)表示@SQL可以是“SELECT * FROM foo”或“DELETE User WHERE 1=1' ;.”

EXEC @SQL表示@SQL是一个对象名。所以我应该使用@Obj

所以,你可以这样做:

DECLARE @Obj varchar(200)
SELECT @Obj = 'dbo.uspCustomHook'
IF OBJECT_ID(@Obj) IS NOT NULL
    EXEC @Obj @p1 = 1, @p2 = 'bob', ...

它避免了延迟名称解析错误。编译批处理/ proc时,如果dbo.uspCustomHook不存在则没有错误。

自从SQL 2000以来我没有使用过这种技术,我不知道SQL 2005(语句级别重新编译)是否足够聪明,如果应该运行@Obj,因为它不存在,所以它不会尝试编译EXEC语句......

它对于跨数据库,相同的实例查询也很有用。您可以在不依赖链接服务器或硬编码数据库名称的情况下配置prd-prod,dev-dev等。

答案 1 :(得分:0)

您可以使用名为sp_MSforeachdb

的未记录的存储过程

答案 2 :(得分:0)

只需使用完全限定的名称来解决这些问题,例如:

<Database Name>.<owner>.<table>

并替换值。

示例:CustomerDatabase.dbo.Users

在你的情况下,它看起来像这样:

exec Branch001.dbo.usp_ComputeDailySales
exec Branch002.dbo.usp_ComputeDailySales
exec Branch003.dbo.usp_ComputeDailySales

这假定一个用户拥有所有这些数据库的权限。

答案 3 :(得分:0)

您可以使用sp_msForEachDB轻松完成此操作。这里的第一个示例将在名为LIKE'Cranch%'的每个数据库上运行proc:

EXECUTE sp_msForEachDB '
IF ''?'' like  ''Branch%''
 BEGIN
    USE ?
    EXECUTE usp_ComputeDailySales
 END
'

这个将在包含该名称的存储过程的每个数据库(无论名称)上运行它:

EXECUTE sp_msForEachDB '
USE ?
IF object_id(''usp_ComputeDailySales'') is not null
    EXECUTE usp_ComputeDailySales
'

喋喋不休地对它们大惊小怪 - 它们起作用,但它们需要一点时间习惯。

附录:虽然这是一个“未记录的功能”,但它是自SQL Server 7.0以来可能更早的版本。有许多文章和样本使用它,可能有许多依赖它的企业系统,其中一些是我建立的。我真的从来没有遇到过任何问题(一旦我得到了它们,而且双重正确,那就是。)