Postgresql插入触发器来设置值

use*_*470 50 postgresql triggers postgresql-9.1

假设在Postgresql中,我有一个表T,其中一个列是C1.

我想在新记录添加到表时触发一个函数T.该函数应检查C1新记录中列的值,如果为null/empty,则将其值设置为'X'.

这可能吗?

Boh*_*ian 79

你需要一个触发器是正确的,因为为列设置默认值对你不起作用 - 默认值仅适用于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'
Run Code Online (Sandbox Code Playgroud)

第2步:创建一个 insert 之前触发的触发器,它允许你更改它们插入的值,调用上面的函数:

CREATE TRIGGER my_trigger
BEFORE INSERT ON T
FOR EACH ROW
EXECUTE PROCEDURE my_trigger_function()
Run Code Online (Sandbox Code Playgroud)

而且你已经完成了.

请参阅上面在SQLFIddle上执行的代码,演示它是否正常工作!


您在评论中提到'X'从子查询中检索值.如果是这样,请更改相关行,如下所示:

NEW.C1 := (select some_column from some_table where some_condition);
Run Code Online (Sandbox Code Playgroud)

  • 你为什么不使用`$$`而是```? (10认同)

Ste*_*eve 9

这是可能的,但您可能最好不要在列上设置默认约束.创建表格时,如下所示:

create table mytable as (
    C1 thetype not null default X
);
Run Code Online (Sandbox Code Playgroud)

这表示如果向表中添加一行并且未指定C1的值,则将使用X代替.not null不是必需的,但是阻止更新使该列归零,假定这是你想要的.

编辑:这只适用于常数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();
Run Code Online (Sandbox Code Playgroud)

new触发器函数中的变量是特殊的,表示正在插入的行.将触发器指定为before insert触发器意味着您可以在将行写入表之前对其进行修改.

第二种解决方案是使用Postgres以不寻常的方式定义的计算列:

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;
Run Code Online (Sandbox Code Playgroud)

这将创建一个函数,该函数占用表的一行并返回一个值,您可以使用它来调用它.但是,表示你可以这样做:

select
    *,
    t.C1
from
    mytable t;
Run Code Online (Sandbox Code Playgroud)

函数声明是不可变的是可选的,但是如果你想索引"列"则需要它.您可以像这样索引此列:

create index on mytable (C1(mytable));
Run Code Online (Sandbox Code Playgroud)