Postgresql
何時檢查 IMMEDIATE 約束以及 Postgres 中的“語句”到底是什麼?
我目前對立即約束檢查的確切時間感到困惑。希望以下範例能解決我的困惑:
create table a ( id int primary key ); create table b ( id int primary key, a_id int not null references a ); /* violates foreign key constraint "b_a_id_fkey" */ with t1 as (insert into b values (100, 200) returning id, a_id) select * from t1; /* ERROR: expensive_exception_thrower */ with t1 as (insert into b values (100, 200) returning id, a_id) select * from t1 where expensive_exception_thrower(t1.a_id) = true;
在第二個查詢中,儘管引用了 t1,但
expensive_exception_thrower
將首先拋出其異常,這導致 fkey 異常被吞噬。當然,有一些解決方法,但是當 Postgres 手冊說在每個語句之後立即檢查 IMMEDIATE 約束時,我想了解“語句”的確切定義。手冊使用術語“語句”的方式表明 with 子句是一個語句,或者至少是“子語句”。這是 PG 版本 14.3。
如評論中所述,語句是前一個語句終止符(通常是分號)和下一個語句終止符之間的所有內容,因此這是一個語句:
with t1 as (insert into b values (100, 200) returning id, a_id) select * from t1 where expensive_exception_thrower(t1.a_id) = true;
處理是這樣的:
- 插入東西。如果違反了主鍵、唯一性或檢查約束,則退出。
- 掃描
returning
結果集。- 對每一行執行一個函式。如果拋出異常就退出。
- 到達結果集的末尾。
- 如果
immediate
違反了參照完整性約束,則退出。- 一直持續到交易結束。
- 如果違反了
deferred
參照完整性約束,則退出。- 犯罪。