我在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的查询:
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.
我做错了什么?
答案 0 :(得分:2)
对于SQL Server 2008,您可以使用MERGE语句,仅使用“WHEN NOT MATCHED BY TARGET”子句来INSERT。不要使用“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, ...);