0

2 つの列に一意の制約があるテーブルがあります。

CREATE TABLE MIGRATION_DICTIONARIES.dbo._TableQueue_ (
    Id INT IDENTITY PRIMARY KEY,
    TableName VARCHAR(250),
    TableFrom VARCHAR(250),
    KeyName VARCHAR(250),
    Processed INT DEFAULT 0,

    CONSTRAINT [UQ_codes] UNIQUE NONCLUSTERED
    (
        TableName, TableFrom
    )
)

私が実装しようとしている手順では、INSERT INTO (...) SELECT を使用して一連のレコードを挿入する必要があります。では、制約を複製する行は無視されますが、select ステートメントによって指定された他の行はすべて保存されるようにするにはどうすればよいでしょうか?

挿入のあるクエリ:

INSERT INTO MIGRATION_DICTIONARIES.dbo._TableQueue_ (TableName, TableFrom, KeyName)
SELECT 'some_table_name', t.name as TableWithForeignKey, c.name as ForeignKeyColumn 
from sys.foreign_key_columns as fk
inner join sys.tables as t on fk.parent_object_id = t.object_id
inner join sys.columns as c on fk.parent_object_id = c.object_id and fk.parent_column_id = c.column_id
where fk.referenced_object_id = (select object_id from sys.tables where name = 'some_table_name')

[編集]次のクエリで終了しました:

MERGE MIGRATION_DICTIONARIES.dbo._TableQueue_ AS T
USING (
    SELECT 'SomeTable' as TableFrom, t.name as TableWithForeignKey, c.name as ForeignKeyColumn 
    from sys.foreign_key_columns as fk
    inner join sys.tables as t on fk.parent_object_id = t.object_id
    inner join sys.columns as c on fk.parent_object_id = c.object_id and fk.parent_column_id = c.column_id
    where fk.referenced_object_id = (select object_id from sys.tables where name = 'SomeTable')
) AS S
ON (T.TableName = S.TableWithForeignKey AND T.TableFrom = S.TableFrom)
WHEN NOT MATCHED BY TARGET THEN
    INSERT (TableName, TableFrom, KeyName)
    VALUES (S.TableFrom, S.TableWithForeignKey, S.ForeignKeyColumn);

しかし、実行すると、まだ制約エラーが発生します:

Violation of UNIQUE KEY constraint 'UQ_codes'. Cannot insert duplicate key in object 'dbo._TableQueue_'. The duplicate key value is (UP_Opiekun, UP_Uczen).
The statement has been terminated.

私は何を間違っていますか?

4

1 に答える 1

2

SQL Server 2008 の場合、INSERT に対して "WHEN NOT MATCHED BY TARGET" 句のみを指定したMERGEステートメントを使用できます。「WHEN MATCHED」句を使用しないでください

より一般的には、使用することもできます

INSERT dbo._TableQueue_
   (....)
SELECT
   ...
FROM
   SOurce S
WHERE
   NOT EXISTS (SELECT *
      FROM dbo._TableQueue_ T
      WHERE
         S.TableName = T.TableName AND S.TableFrom = T.TableFrom
      )

コメントの後:

MERGE INTO dbo._TableQueue_ T
USING Source S
       ON S.TableName = T.TableName AND S.TableFrom = T.TableFrom
WHEN NOT MATCHED BY TARGET THEN
   INSERT (...)
   VALUES (S.x. S.y, ...);
于 2013-05-15T07:16:05.207 に答える