SQL Server 2014 - слияние - синтаксические ошибки - PullRequest
0 голосов
/ 13 июня 2018

У меня есть этот запрос с оператором слияния, выполняющимся как часть более крупного сценария с использованием foreachdb в SQL Server.Я получаю случайные синтаксические ошибки -

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
'

1 Ответ

0 голосов
/ 09 июля 2018

Вот несколько замечаний по коду.

Почему вы используете 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...