如何解决如果行违反主键,则插入错误表
我有这张桌子:
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','PARIS'
UNION ALL
SELECT '2','PARIS'
我想在 1st
中插入 3rd
行和 TEST
行,在 2nd row
中插入 TEST_ERROR
。这可以通过 sql 查询实现。我的预期输出是
TEST
ID | C_STATUS | SS |
---|---|---|
1 | 90 | 巴黎 |
2 | 90 | 巴黎 |
TEST_ERROR
ID | C_STATUS | SS |
---|---|---|
1 | 90 | 巴黎 |
我尝试过类似下面的方法,但显然不起作用
BEGIN TRY
insert into test
SELECT '1','PARIS'
END TRY
BEGIN CATCH
insert into test
.........
END CATCH
解决方法
您可以在 INSTEAD OF INSERT
上创建 TEST
触发器。使用 ROW_NUMBER()
窗口函数来识别那些重复项,并且只将其中一行插入到 TEST
中,将那些重复项插入到 TEST_ERROR
CREATE TRIGGER TR_TEST
ON TEST
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO TEST (ID,C_status,SS)
SELECT ID,SS
FROM
(
SELECT ID,SS
RN = ROW_NUMBER() OVER(PARTITION BY ID,SS ORDER BY ID)
FROM INSERTED
) i
WHERE i.RN = 1
INSERT INTO TEST_ERROR (ID,SS,RN = ROW_NUMBER() OVER(PARTITION BY ID,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','PARIS'
UNION ALL
SELECT '2','PARIS'
),cte_distinctdata as
(
SELECT *,row_number() over(partition by id,ss order by id) as rnk
FROM cte_alldata
)
INSERT INTO Error_Table
SELECT id,ss from cte_distinctdata where rnk >1
id | c_status | ss |
---|---|---|
1 | 90 | 巴黎 |
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。