假设在Postgresql中,我有一个名为
当向表
这是否可行?
T
的表,其中一个列为C1
。当向表
T
添加新纪录时,我想触发一个函数。该函数应检查新记录中列C1
的值,如果它为空/空白,则将其值设置为'X'
。这是否可行?
T
的表,其中一个列为C1
。T
添加新纪录时,我想触发一个函数。该函数应检查新记录中列C1
的值,如果它为空/空白,则将其值设置为'X'
。你是正确的,你需要触发器,因为为列设置默认值对你没有作用——默认值只适用于 null
值,并且不能帮助你防止空白值。
在 postgres 中,创建触发器有几个步骤:
步骤 1:创建一个返回类型为 trigger
的函数:
CREATE FUNCTION my_trigger_function()
RETURNS trigger AS $$
BEGIN
IF NEW.C1 IS NULL OR NEW.C1 = '' THEN
NEW.C1 := 'X';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql
步骤2:创建一个触发器,调用上述函数并在BEFORE INSERT
时触发,这允许您在值进入表之前进行更改:
CREATE TRIGGER my_trigger
BEFORE INSERT ON T
FOR EACH ROW
EXECUTE PROCEDURE my_trigger_function()
完成了。
您在评论中提到值'X'
是从子查询中检索出来的。如果是这样,请将相关行更改为以下内容:
NEW.C1 := (select some_column from some_table where some_condition);
$$
而是用'
? - Stefan Falk$$
时存在分隔符问题。直到你指出这一点,我一直无法使用函数! - Noumenonnew.c1 := coalesce (new.c1,X);
- Bernardo Jerez如果需要,你可以这样做,但最好还是在列上设置默认约束。创建表时应该像这样:
create table mytable as (
C1 thetype not null default X
);
这意味着如果您向表中添加一行并且没有指定C1的值,则会使用X。非空不是必需的,但可以防止更新将该列置空(假设这是您想要的)。
编辑:仅适用于常量X,从您的评论中看来有两种可能的解决方案。
使用触发器可能如下所示:
create function update_row_trigger() returns trigger as $$
begin
if new.C1 is NULL then
new.C1 := X;
end if;
return new;
end
$$ language plpgsql;
create trigger mytrigger before insert on mytable for each row execute procedure update_row_trigger();
new
变量是特殊的,表示正在插入的行。将触发器指定为before insert
触发器意味着您可以在写入表之前修改行。create or replace function C1(row mytable) returns columntype immutable as $$
begin
return X; -- where X is an expression using values from `row`
end
$$ language plpgsql;
这将创建一个函数,它接受您的表格行并返回一个值,您可以使用“.”符号调用它,这意味着您可以执行:
select
*,
t.C1
from
mytable t;
函数声明为不可变的是可选的,但如果您想索引“列”,则需要该声明。您可以像这样索引此列:
create index on mytable (C1(mytable));