[英]Insert into error table if the rows violates primary key
我有这张桌子:
CREATE TABLE TEST
(
ID INT NOT NULL,
C_status INT NOT NULL,
SS VARCHAR(10),
CONSTRAINT [PK_TBL]
PRIMARY KEY CLUSTERED ([ID] ASC, [C_status ] ASC, [SS ] ASC)
)
现在我正在尝试使用
INSERT INTO SELECT ...
数据中会有重复。 如何仅在一个表中插入唯一值并在另一表中插入重复值。 例如,如果我执行以下操作
INSERT INTO TEST
SELECT '1','90','PARIS'
UNION ALL
SELECT '1','90','PARIS'
UNION ALL
SELECT '2','90','PARIS'
我想在TEST
中插入1st
行和3rd
行,在TEST_ERROR
中插入2nd row
。 这可能与 SQL 查询。 我预期的 output 是
TEST
ID | C_STATUS | 党卫军 |
---|---|---|
1 | 90 | 巴黎 |
2 | 90 | 巴黎 |
TEST_ERROR
ID | C_STATUS | 党卫军 |
---|---|---|
1 | 90 | 巴黎 |
我已经尝试过类似下面的东西,但它显然没有用
BEGIN TRY
insert into test
SELECT '1','90','PARIS'
UNION ALL
SELECT '1','90','PARIS'
UNION ALL
SELECT '2','90','PARIS'
END TRY
BEGIN CATCH
insert into test
.........
END CATCH
您可以在TEST
上创建INSTEAD OF INSERT
触发器。 使用ROW_NUMBER()
window function 来识别这些重复项,并且仅将其中一行插入TEST
并将这些重复项插入TEST_ERROR
CREATE TRIGGER TR_TEST
ON TEST
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO TEST (ID, C_status, SS)
SELECT ID, C_status, SS
FROM
(
SELECT ID, C_status, SS
RN = ROW_NUMBER() OVER(PARTITION BY ID, C_status, SS ORDER BY ID)
FROM INSERTED
) i
WHERE i.RN = 1
INSERT INTO TEST_ERROR (ID, C_status, SS)
SELECT ID, C_status, SS
FROM
(
SELECT ID, C_status, SS,
RN = ROW_NUMBER() OVER(PARTITION BY ID, C_status, SS ORDER BY ID)
FROM INSERTED
) i
WHERE i.RN > 1
END
当您作为批处理插入时,它是全有或全无操作。 您不能专门将错误行发送到错误文件。 如果你想在行级别做,你必须有 CURSOR 来发送错误行。
但是,您可以应用 ROW_NUMBER() 并过滤重复数据并发送到错误表。
--duplicate data
;with cte_alldata(id, c_status, ss) as
(
SELECT '1','90','PARIS'
UNION ALL
SELECT '1','90','PARIS'
UNION ALL
SELECT '2','90','PARIS'
)
, cte_distinctdata as
(
SELECT *, row_number() over(partition by id, c_status, ss order by id) as rnk
FROM cte_alldata
)
INSERT INTO Error_Table
SELECT id, c_status, ss from cte_distinctdata where rnk >1
ID | c_status | ss |
---|---|---|
1 | 90 | 巴黎 |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.