使答案組完成。使用rules。
首先,我們將創建服務功能,能夠從SQL語句引發異常:
create or replace function public.fn_raise(msg text, cond boolean = true)
returns bool
immutable
language plpgsql
as $$
begin
if cond then
raise exception '%', msg;
end if;
return false;
end $$;
接下來,讓我們創建測試表:
create table t(i int, d timestamptz not null default current_timestamp);
最後,規則:
create or replace rule rul_t_insert as on insert to t
where new.d <> current_timestamp
do also
select fn_raise(format('Can not insert %s into table t', new.d), new.d <> current_timestamp);
讓我們測試它:
postgres=# insert into t(i) values(1) returning *;
┌───┬───────────────────────────────┐
│ i │ d │
╞═══╪═══════════════════════════════╡
│ 1 │ 2017-07-28 12:31:37.255392+03 │
└───┴───────────────────────────────┘
postgres=# insert into t(i,d) values(1,null) returning *;
ERROR: null value in column "d" violates not-null constraint
DETAIL: Failing row contains (1, null).
postgres=# insert into t(i,d) values(2,'2000-10-10') returning *;
ERROR: Can not insert 2000-10-10 00:00:00+03 into table t
我提的問題只有insert
但如果你也想阻止這一領域的更新,你可以創建另一個規則:
create or replace rule rul_t_update as on update to t
where new.d <> old.d
do also
select fn_raise(format('Can not change t.d to %s', new.d), new.d <> old.d);
測試:
postgres=# update t set i = 3 where i = 1 returning *;
┌───┬───────────────────────────────┐
│ i │ d │
╞═══╪═══════════════════════════════╡
│ 3 │ 2017-07-28 12:31:37.255392+03 │
└───┴───────────────────────────────┘
postgres=# update t set i = 4, d = current_timestamp where i = 3 returning *;
ERROR: Can not change t.d to 2017-07-28 12:39:18.963852+03
感謝timestamptz建議! –