正如 Patrick 所说,您必须指定一个许可目标,以便 Postgres 验证在您有机会操作数据之前不会拒绝数据。
另一种不使用第二个表的方法是在基表上创建一个视图,将所有内容转换为 varchar,然后使用INSTEAD OF 触发器在视图上尝试插入时填充基表。
例如,下面的表 tab1 有一个整数列。视图 v_tab1 有一个 varchar,因此任何插入都适用于该视图。然后,instead of 触发器会检查输入的值是否为数字,如果不是,则使用 0 代替。
create table tab1 (i1 int, v1 varchar);
create view v_tab1 as select cast(i1 as varchar) i1, v1 from tab1;
create or replace function v_tab1_insert_trgfun() returns trigger as
$$
declare
safe_i1 int;
begin
if new.i1 ~ '^([0-9]+)$' then
safe_i1 = new.i1::int;
else
safe_i1 = 0;
end if;
insert into tab1 (i1, v1) values (safe_i1, new.v1);
return new;
end;
$$
language plpgsql;
create trigger v_tab1_insert_trigger instead of insert on v_tab1 for each row execute procedure v_tab1_insert_trgfun();
现在无论值如何,插入都可以工作
insert into v_tab1 values ('12','hello');
insert into v_tab1 values ('banana','world');
select * from tab1;
给予
|i1 |v1 |
+-----+-----+
|12 |hello|
|0 |world|
拨弄:http://sqlfiddle.com/#!15/9af5ab/1