我开始交易 在事务中,我有一个插入查询,它违反了几个约束。 因为我不想回滚事务,所以我可以继续,我用以下方式结束插入查询:
对于冲突,什么也不做
注意:因为有几件事可能会出错,我没有指定任何目标
不幸的是,我在控制台中收到约束违规错误,我必须回滚事务。 我做错了什么?
我希望能够在交易中继续查询。
代码:
BEGIN;
INSERT INTO suez.gebruikers(cprid, upn, inlognaam, peoplesoft_id, actief
, locatie, naam, familienaam, voorvoegsels, initialen, voornamen
, email, opmerking)
VALUES (74965, null, null, null, true, 'VUMC', 'Moonen JEF Justine',
'Moonen', null, 'JEF', 'Justine', '[email protected]', null)
ON CONFLICT DO NOTHING;
```
ERROR: new row for relation "gebruikers" violates check constraint "chk_actief_upn"
DETAIL: Failing row contains (74965, null, null, [email protected], VUMC, Moonen JEF Justine, Moonen, null, JEF, Justine, t, null, 2024-05-07, 2024-05-07, null, null, f).
Table "suez.gebruikers"
Column | Type | Collation | Nullable | Default
-------------------+-----------------------------+-----------+----------+---------
cprid | integer | | not null |
inlognaam | text | | |
upn | text | | |
email | text | | |
locatie | text | | not null |
naam | text | | not null |
familienaam | text | | |
voorvoegsels | text | | |
initialen | text | | |
voornamen | text | | |
actief | boolean | | not null | false
opmerking | text | | |
date_created | date | | not null | now()
date_changed | date | | not null | now()
last_login | timestamp without time zone | | |
peoplesoft_id | text | | |
preferred_account | boolean | | not null | false
Indexes:
"gebruikers_pkey" PRIMARY KEY, btree (cprid)
"uk_inlognaam" UNIQUE CONSTRAINT, btree (inlognaam)
"un_lokatie_email" UNIQUE CONSTRAINT, btree (locatie, email)
"un_lokatie_peoplesoft_id" UNIQUE CONSTRAINT, btree (locatie, peoplesoft_id)
"un_lokatie_upn" UNIQUE CONSTRAINT, btree (locatie, upn)
Check constraints:
"chk_actief_upn" CHECK (actief = false OR actief AND upn IS NOT NULL)
Referenced by:
TABLE "gebruikers_rollen_link" CONSTRAINT "fk_cprid" FOREIGN KEY (cprid) REFERENCES gebruikers(cprid)
Triggers:
trigger_record_changed BEFORE UPDATE ON gebruikers FOR EACH ROW EXECUTE FUNCTION record_changed()
INSERT ... ON CONFLICT
仅捕获由唯一违规引起的错误。其他错误(例如您遇到的检查约束错误)不受影响,权限错误或其他错误也是如此。你必须以其他方式处理它们。
如果您的事务很短(大多数事务都应该如此),只需回滚并执行其他操作即可。
如果是长事务(批处理作业),回滚事务会很麻烦,可以使用保存点:
BEGIN;
SAVEPOINT a;
INSERT ...;
/* if there is an error */
ROLLBACK TO SAVEPOINT a;
/* continue the transaction */
COMMIT;
警告: 非常谨慎地使用保存点。如果您在单笔交易中拥有太多此类信息,您的性能可能会受到相当大的影响。