微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如果行违反主键,则插入错误表

如何解决如果行违反主键,则插入错误表

我有这张桌子:

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 举报,一经查实,本站将立刻删除。