【问题标题】:SQL Server 2014 - Merge - syntax errorsSQL Server 2014 - 合并 - 语法错误
【发布时间】:2018-11-22 14:10:22
【问题描述】:

我在 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
'

【问题讨论】:

  • 我想知道在您的foreachdb 循环期间,临时实体#UnMatchedTransactions 是否超出范围,因为每次迭代都会启动新连接? -- 自从我做任何 sql-server 以来已经有几年了,所以对这个评论持保留态度,但如果它有帮助那就太好了。
  • 尝试使用方括号将所有对象的名称括起来,甚至包括变量数据库名称的?

标签: sql-server database tsql merge syntax-error


【解决方案1】:

以下是对代码的一些观察。

为什么要使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    相关资源
    最近更新 更多