sql-server - SQL Server 2014 - 合并 - 语法错误

标签 sql-server database tsql merge syntax-error

我在 SQL Server 中使用 foreachdb 将此查询与合并语句作为较大脚本的一部分运行。我不断收到随机语法错误 -

Msg 156, Level 15, State 1, Line 59
Incorrect syntax near the keyword 'AS'.
Msg 102, Level 15, State 1, Line 72
Incorrect syntax near ')'.

我的脚本有什么问题?当合并在 foreachdb 之外运行时,它运行良好,没有任何错误。在 foreachdb 中时,它每次都会失败并出现不同的错误。

USE RedshiftDatabase;


EXEC sp_MSforeachdb
'

BEGIN
USE ?;

        TRUNCATE TABLE #UnMatchedTransactions


        PRINT(''truncate complete'');


        INSERT INTO #UnMatchedTransactions
        SELECT
            DB_NAME(),
            TxnID,
            BatchID,
            DateCreated,
            CURRENT_TIMESTAMP,
            CURRENT_TIMESTAMP,
            0
        FROM
            UnMatchedTransactions;

        SELECT db_name(),''done'';
        SELECT ClientName, COUNT(1) FROM #UnMatchedTransactions GROUP BY ClientName;

        CHECKPOINT;

        BEGIN TRANSACTION merge_tran


                MERGE INTO RedshiftDatabase.dbo.UnMatchedTransactions AS TARGET
                USING  #UnMatchedTransactions AS SOURCE
                ON  
                (
                    TARGET.ClientName = SOURCE.ClientName 
                AND 
                    TARGET.TxnID = SOURCE.TxnID
                AND 
                    TARGET.BatchID = SOURCE.BatchID
                )
                WHEN MATCHED AND (TARGET.DateCreated <> SOURCE.DateCreated)
                THEN
                    UPDATE SET 
                        DateCreated  = SOURCE.DateCreated, 
                        UpdatedTS = CURRENT_TIMESTAMP
                WHEN NOT MATCHED BY TARGET
                THEN
                INSERT ( ClientName,
                        TxnID,
                        BatchID,
                        DateCreated
                        ) 
                VALUES (SOURCE.ClientName,
                        SOURCE.TxnID,
                        SOURCE.BatchID,
                        SOURCE.DateCreated
                        )
                WHEN NOT MATCHED BY SOURCE 
                THEN 
                    UPDATE SET 
                            TARGET.IsDeleted = 1,
                            TARGET.UpdatedTS = CURRENT_TIMESTAMP
                ;

        END TRANSACTION merge_tran;

        CHECKPOINT;

        SELECT db_name(),''Mergedone'';
        SELECT BL_ClientName, COUNT(1) FROM RedshiftDatabase.dbo.UnMatchedTransactions GROUP BY ClientName;

    END;
END
'

最佳答案

这里是对代码的一些观察。

为什么要使用 sp_MSforeachdb?您可以使用 CTE 通过使用系统表列出服务器上的所有数据库名称,然后您可以编写动态 sql 来迭代合并语句的列表?

这是针对您的问题的建议解决方案。

BEGIN
    USE ?;
    -- TO DO Check if table exists
    TRUNCATE TABLE #UnMatchedTransactions
    PRINT('truncate complete');
    -- To DO create #UnMatchedTransactions each time as database name changed so scope changed and table doesn't exist in new scope. Create table in each iteratation
    -- Second option use ##UnMatchedTransactions and delete row per database at the end
    INSERT INTO #UnMatchedTransactions
    SELECT
        DB_NAME(),
        TxnID,
        BatchID,
        DateCreated,
        CURRENT_TIMESTAMP,
        CURRENT_TIMESTAMP,
        0
    FROM
        UnMatchedTransactions;

    SELECT db_name(),'done';
    SELECT ClientName, COUNT(1) FROM #UnMatchedTransactions GROUP BY ClientName;

    CHECKPOINT;

    BEGIN TRANSACTION merge_tran
        MERGE INTO RedshiftDatabase.dbo.UnMatchedTransactions AS TARGET
        USING  #UnMatchedTransactions AS SOURCE
            ON  
            (
                TARGET.ClientName = SOURCE.ClientName 
            AND 
                TARGET.TxnID = SOURCE.TxnID
            AND 
                TARGET.BatchID = SOURCE.BatchID
            )
            WHEN MATCHED AND (TARGET.DateCreated <> SOURCE.DateCreated)
            THEN
                UPDATE SET 
                    DateCreated  = SOURCE.DateCreated, 
                    UpdatedTS = CURRENT_TIMESTAMP
            WHEN NOT MATCHED BY TARGET
            THEN
            INSERT ( ClientName,
                    TxnID,
                    BatchID,
                    DateCreated
                    ) 
            VALUES (SOURCE.ClientName,
                    SOURCE.TxnID,
                    SOURCE.BatchID,
                    SOURCE.DateCreated
                    )
            WHEN NOT MATCHED BY SOURCE 
            THEN 
                UPDATE SET 
                        TARGET.IsDeleted = 1,
                        TARGET.UpdatedTS = CURRENT_TIMESTAMP
            ;

    END TRANSACTION merge_tran;

    CHECKPOINT;

    SELECT db_name(),'Mergedone';
    SELECT BL_ClientName, COUNT(1) FROM RedshiftDatabase.dbo.UnMatchedTransactions GROUP BY ClientName;

    END;
    -- if using Second option then drop here so that temp tables cleaning would be done for each databaseuse
END

关于sql-server - SQL Server 2014 - 合并 - 语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50829689/

相关文章:

java - 将 SQL Server 2008 连接到 Java : Login failed for user error

sql-server - 为什么SQL Server View 需要每隔一段时间刷新一次

java - Android 和 Windows Phone 之间共享数据库

c++ - stx-btree 存储在磁盘上

sql - 在 SQL 的 CASE 中使用 LIKE

sql - 无法为 SQL Server 中的对象分配空间

sql-server - 将数据从 SQL Server 流式传输到 Azure 数据仓库

mysql - 显示两个日期之间的日期列表?

sql - 无法在 EXEC() 后获得 @@ERROR 并出现错误

sql-server - 禁用表中的索引后出错