将SELECT结果用作循环中的变量

时间:2012-09-28 17:57:24

标签: sql sql-server sql-server-2008 sql-server-2008-r2

我在这里和其他地方搜索过,还没有找到答案。希望我没有错过它。

使用SQL Server Management Studio 2008 R2。

我的服务器上有n个特定的数据库(还有其他数据库,但我只对其中一些感兴趣)

每个数据库都有一个表,它们都有相同的名称。唯一的区别是DB名称。我想将这些表聚合在一起,在不同的数据库上创建一个大表(与其他数据库不同)。

我可以从查询结果中获取数据库名称。

N未知。

循环是否可以解决这个问题?

我正在考虑下面的伪代码:

Set @dbnames = SELECT DISTINCT dbname FROM MyServer.dbo.MyTable

For each @name in @dbnames
    INSERT INTO ADifferentDB.dbo.MyOtherTable
    SELECT * FROM @name.dbo.table
Next name

(显然我也是新手使用SQL变量,正如你所看到的那样)

3 个答案:

答案 0 :(得分:4)

你的第一个问题是关于迭代数据库:你可以用光标做到这一点

然后你有另一个问题,执行一个查询,其中部分是变量(数据库的名称)。您可以使用execute函数执行此操作。

所有这些与此相似:

DECLARE @query VARCHAR(max)
DECLARE @dbname VARCHAR(100)
DECLARE my_db_cursor CURSOR
            FOR SELECT DISTINCT dbname FROM MyServer.dbo.MyTable
OPEN my_db_cursor 
FETCH NEXT FROM my_db_cursor 
INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @query = 'INSERT INTO ADifferentDB.dbo.MyOtherTable
                   SELECT * FROM ' + @dbname + '.dbo.table'
    EXECUTE(@query)  

    FETCH NEXT FROM my_db_cursor 
    INTO @dbname
END
CLOSE my_db_cursor 
DEALLOCATE my_db_cursor 

答案 1 :(得分:1)

您要做的是为行级操作定义CURSOR。这里有一些doc

答案 2 :(得分:1)

我建议使用sp_MSForEachDB

EXEC sp_MSForEachDB '
-- Include only the databases you care about.
IF NOT EXISTS (
    SELECT *
    FROM MySever.dbo.MyTable
    WHERE dbname = ''?''
)
    -- Exit if the database is not in your table.
    RETURN

-- Otherwise, perform your insert.
INSERT INTO ADifferentDB.dbo.MyOtherTable
SELECT * FROM ?.dbo.table
'

在这种情况下,?是一个用服务器上的每个数据库替换的标记。