SCD2 + оператор слияния + SQL Server - PullRequest
1 голос
/ 15 апреля 2010

Я пытаюсь работать с инструкцией MERGE для вставки / обновления таблицы размеров типа SCD2

Мой источник - табличная переменная для объединения с таблицей измерений.

Мой оператор MERGE выдает ошибку как:

Таблица целей 'DM.DATA_ERROR.ERROR_DIMENSION' из Оператор INSERT не может быть ни на сторона (первичный ключ, внешний ключ) отношения, когда предложение FROM содержит вложенную вставку, ОБНОВЛЕНИЕ, DELETE, или MERGE оператор. Найденный ограничение ссылки 'FK_ERROR_DIMENSION_to_AUDIT_CreatedBy'.

Мое утверждение MERGE:

DECLARE @DATAERROROBJECT AS [ERROR_DIMENSION]

INSERT INTO DM.DATA_ERROR.ERROR_DIMENSION
SELECT  ERROR_CODE,
    DATA_STREAM_ID,
    [ERROR_SEVERITY],
    DATA_QUALITY_RATING,
    ERROR_LONG_DESCRIPTION,
    ERROR_DESCRIPTION,
    VALIDATION_RULE,
    ERROR_TYPE,
    ERROR_CLASS,
    VALID_FROM,
    VALID_TO,
    CURR_FLAG,
    CREATED_BY_AUDIT_SK,
    UPDATED_BY_AUDIT_SK

FROM (MERGE DM.DATA_ERROR.ERROR_DIMENSION ED USING @DATAERROROBJECT OBJ
     ON(ED.ERROR_CODE = OBJ.ERROR_CODE AND ED.DATA_STREAM_ID = OBJ.DATA_STREAM_ID)     WHEN NOT MATCHED THEN    INSERT VALUES(
         OBJ.ERROR_CODE
        ,OBJ.DATA_STREAM_ID
        ,OBJ.[ERROR_SEVERITY]
        ,OBJ.DATA_QUALITY_RATING
        ,OBJ.ERROR_LONG_DESCRIPTION
        ,OBJ.ERROR_DESCRIPTION
        ,OBJ.VALIDATION_RULE
        ,OBJ.ERROR_TYPE
        ,OBJ.ERROR_CLASS
        ,GETDATE()
        ,'9999-12-13'
        ,'Y'
        ,1
        ,1
        ) WHEN MATCHED AND ED.CURR_FLAG = 'Y'
             AND (      ED.[ERROR_SEVERITY] <> OBJ.[ERROR_SEVERITY]
                   OR   ED.[DATA_QUALITY_RATING] <> OBJ.[DATA_QUALITY_RATING]
                   OR   ED.[ERROR_LONG_DESCRIPTION] <> OBJ.[ERROR_LONG_DESCRIPTION]
                   OR   ED.[ERROR_DESCRIPTION] <> OBJ.[ERROR_DESCRIPTION]
                   OR   ED.[VALIDATION_RULE] <> OBJ.[VALIDATION_RULE]
                   OR   ED.[ERROR_TYPE] <> OBJ.[ERROR_TYPE]
                   OR   ED.[ERROR_CLASS] <> OBJ.[ERROR_CLASS] ) THEN UPDATE SET ED.CURR_FLAG = 'N', ED.VALID_TO = GETDATE()
        OUTPUT $ACTION ACTION_OUT, 
                           OBJ.ERROR_CODE ERROR_CODE,
                           OBJ.DATA_STREAM_ID DATA_STREAM_ID,
                           OBJ.[ERROR_SEVERITY] [ERROR_SEVERITY],
                           OBJ.DATA_QUALITY_RATING DATA_QUALITY_RATING,
                           OBJ.ERROR_LONG_DESCRIPTION ERROR_LONG_DESCRIPTION,
                           OBJ.ERROR_DESCRIPTION ERROR_DESCRIPTION,
                           OBJ.VALIDATION_RULE VALIDATION_RULE,
                           OBJ.ERROR_TYPE ERROR_TYPE,
                           OBJ.ERROR_CLASS ERROR_CLASS,
                           GETDATE() VALID_FROM,
                           '9999-12-31' VALID_TO,
                           'Y' CURR_FLAG,
                           555 CREATED_BY_AUDIT_SK,
                           555 UPDATED_BY_AUDIT_SK
                           ) AS MERGE_OUT WHERE MERGE_OUT.ACTION_OUT = 'UPDATE';

Что я делаю не так?

Ответы [ 2 ]

18 голосов
/ 02 декабря 2010

На самом деле проблема является известной ошибкой в ​​SQL Server. Проблема заключается в использовании предложения OUTPUT оператора DML с синтаксисом INSERT ... SELECT. Обходными решениями могут быть либо отсутствие внешних ключей, ссылающихся на таблицу измерений, либо вставка результатов MERGE ... OUTPUT во временную таблицу, а затем вставка в фактическую таблицу измерений:

http://connect.microsoft.com/SQLServer/feedback/details/435031/unable-to-perform-slowly-changing-dimension-updates-on-a-dimension-table-with-a-foreign-key

0 голосов
/ 15 апреля 2010

Я думаю, что вашей фундаментальной ошибкой является тот факт, что вы, кажется, ожидаете, что MERGE возвращает набор данных - как SELECT .... делает - он делает не .

Я не верю, что вы можете использовать

SELECT (list of fields)
FROM (MERGE DM.DATA_ERROR.ERROR_DIMENSION ED 
      USING @DATAERROROBJECT OBJ
      ON(ED.ERROR_CODE = OBJ.ERROR_CODE AND ED.DATA_STREAM_ID = OBJ.DATA_STREAM_ID)
   .......

Что вам нужно сделать, это:

  • загрузить данные для объединения в отдельную промежуточную таблицу
  • затем выполните оператор MERGE как отдельный оператор для целевой таблицы, используя эту промежуточную таблицу в качестве источника

Проверьте эти ресурсы:

...