【问题标题】:SQL Run query across multiple DatabasesSQL 跨多个数据库运行查询
【发布时间】:2015-12-07 10:47:57
【问题描述】:

我希望在多个数据库上运行查询。我见过这个函数;

sp_MsForEachDb

这没关系,但它贯穿所有数据库,我只想使用其中的一些。有没有办法选择运行哪些数据库?同样在这些数据库中,我们有分支(所以所有表都有一个 BranchID 列)。例如,数据库 1 可能有分支 4、5 和 6,我们只需要分支 5。数据库 2 也可能有分支 4、5 和 6,但在这个中我们需要分支 4 和 5。有没有办法选择哪个分支是根据哪个数据库运行的?

这可以在 SSIS 或类似的东西上完成吗?

希望这是有道理的!

【问题讨论】:

  • 我想从 sys.databases 中选择一个,加上分支的“where in”语句。
  • 如何使用 sys.databases?我以前没有这样做过...
  • 这是一个包含数据库信息的sql server master db视图。试试select * from sys.databases。还有msdnmsdn.microsoft.com/en-us/library/ms178534.aspx
  • 您可以从那里获取 db_id、名称等,以及其他可能有用的信息。

标签: sql sql-server multiple-databases


【解决方案1】:

我使用一个简单的游标来完成此操作....它非常简单,您可以针对数据库列表运行其中的任何语句。

    --Drop temporary tables if they already exists.
IF OBJECT_ID('tempdb..#DatabaseNames') IS NOT NULL
    DROP TABLE #DatabaseNames

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    DROP TABLE #Results

--Create a temporary table.
CREATE TABLE #DatabaseNames
(
    DBName varchar(100),
    Active bit
)

GO

--Create a temporary table to store results.
CREATE TABLE #Results
(
    FirstName varchar(100),
    WebLogin varchar(100)
)

GO

--It's the long way to do this but just showing for the sake of the example.
INSERT INTO #DatabaseNames
VALUES ('Database1', 1)

INSERT INTO #DatabaseNames
VALUES ('Database2', 0)

INSERT INTO #DatabaseNames
VALUES ('Database3', 1)

INSERT INTO #DatabaseNames
VALUES ('TIER1', 1)

INSERT INTO #DatabaseNames
VALUES ('Northwind', 1)

DECLARE @DBName varchar(20)
DECLARE @SQL   varchar(2000)

--Start cursor
DECLARE LoopCursor CURSOR FOR
    SELECT DBName AS 'DBName'
    FROM #DatabaseNames
    WHERE DBName NOT IN ('TIER1', 'Northwind')
    AND Active = 1

    OPEN LoopCursor

    FETCH NEXT FROM LoopCursor
    INTO @DBName

    WHILE @@FETCH_STATUS = 0
    BEGIN

        SET @SQL = '
        INSERT INTO #Results
        SELECT FirstName, WebLogin
        FROM ' + @DBName + '.dbo.Users
        WHERE FirstName = ''User1''
        AND LastName = ''User1''
        AND WebLogin = ''User1Login'''

        EXEC(@SQL)
        --Print @DBName

        FETCH NEXT FROM LoopCursor
        INTO @DBName
    END

    SELECT *
    FROM #Results

    CLOSE LoopCursor
    DEALLOCATE LoopCursor

我再次修改了我的答案,以配合您关于希望将所有结果放在一个表中的最后评论。您可以添加另一个临时表并将数据插入其中。然后一旦完成,在关闭光标之前从该表中选择。至于WHERE子句中有很多条件,你可以用2个单引号把单引号括起来,所以WHERE name = 'MyName'变成WHERE name = ''MyName''

顺便说一句,我的游标不是对 CPU 最友好的,而且大多数人不喜欢使用它们,但它们有它们的位置。我并不是说这是最好的解决方案,但效果很好。我们有超过 75 个客户数据库,都具有相同的结构,我每天都使用它来更新用户字段和其他表字段。它在这么多数据库上执行这么多语句时运行得非常快。

【讨论】:

  • 这看起来真的很有用。没有配置表,我可以用什么替换?
  • 啊,我明白了。有没有办法让结果都在一个表中,而不是每个数据库一个表中。 Union All 什么的。否则,我将不得不将每个表格复制并粘贴到 Excel 中(大约有 75 个)。
  • 每个数据库的字段都一样吗?
  • 是的,应该没问题。此外,我在 where 子句中有很多日期标准,如果它们需要单引号,我该如何输入它们?非常感谢您对此的帮助!
猜你喜欢
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多