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)
这是可能的,但您可能最好不要在列上设置默认约束.创建表格时,如下所示:
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)
归档时间: |
|
查看次数: |
53443 次 |
最近记录: |