简体   繁体   English

带有 union all 的存储过程循环

[英]Stored procedure loop with union all

I need help to optimize the stored procedure shown here.我需要帮助来优化此处显示的存储过程。 It works, but when it runs it generates a select script for each database.它可以工作,但是当它运行时,它会为每个数据库生成一个选择脚本。 I need the stored procedure to union all select statements.我需要存储过程来联合所有选择语句。

Does anyone know how to make this work?有谁知道如何使这项工作?

SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

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

CREATE TABLE #database
(
    id INT IDENTITY PRIMARY KEY, 
    name sysname
)

SET NOCOUNT ON

BEGIN

INSERT INTO #database(name) 
    SELECT name
    FROM master.sys.databases 
    WHERE name IN (SELECT [DATABASE] COLLATE Latin1_General_CI_AS  
                   FROM SETTINGS.DBO.SETTINGS
                   WHERE [KEY] = 'DB_NAME' AND SETTING = '1' )
    ORDER BY name
END

DECLARE @id INT, @cnt INT, @sql NVARCHAR(max), @currentDb sysname;

SELECT @id = 1, @cnt = MAX(id)
FROM #database

WHILE @id <= @cnt
BEGIN
    SELECT @currentDb = name
    FROM #database
    WHERE id = @id

    SET @sql =  'select * FROM ' + @currentDb + '.dbo.People'
    PRINT @sql

    EXEC (@sql);  
    
    PRINT '--------------------------------------------------------------------------'
    SET @id = @id + 1; 
END

DROP TABLE #database
END

Build your dynamic string inside your loop and only execute it once the loop has finished.在循环中构建动态字符串,只有在循环完成后才执行它。

WHILE @id <= @cnt BEGIN
    SELECT @currentDb = [name]
    FROM #database
    WHERE id = @id;

    SET @sql = @sql + CASE WHEN LEN(@sql) > 0 THEN ' union all ' ELSE '' END
        + 'SELECT * FROM ' + QUOTENAME(@currentDb) + '.dbo.People';

    SET @id = @id + 1; 
END;
IF len(@sql) > 0 BEGIN
    print @sql
    exec (@sql); 
END;

Note use QUOTENAME to prevent SQL injection issues - even if just by accident.注意使用QUOTENAME来防止 SQL 注入问题 - 即使只是偶然。

I changed the code and copied and tried below link, and it works perfect.我更改了代码并复制并尝试了下面的链接,它运行完美。 Thanks for your help.谢谢你的帮助。

How do you use a cursor to combine data in a Union All? 你如何使用游标将数据合并到一个联合中?

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql = @sql +
'UNION ALL SELECT column1 FROM ' + QUOTENAME(name) + '..tableA' + CHAR(10)
FROM sys.databases 
WHERE [name] NOT IN ('master', 'tempdb', 'model', 'msdb')

SELECT @sql = STUFF(@sql, 1, 10, '')

PRINT @sql
EXEC (@sql)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM