Sql 如何避免;“空白”;在使用触发器将数据插入视图时插入&;插入程序?
我正在尝试从PostgreSQL视图上的Sql 如何避免;“空白”;在使用触发器将数据插入视图时插入&;插入程序?,sql,postgresql,stored-procedures,views,plpgsql,Sql,Postgresql,Stored Procedures,Views,Plpgsql,我正在尝试从PostgreSQL视图上的insert或update调用更新表。以下是我所做工作的简化示例: [Person] table: id | lastname | firstname | city | age [Person_View] table: id | lastname | firstname | city 以下是触发器和相关程序: CREATE TRIGGER tg_update_person_view INSTEAD OF INSERT OR UPDATE OR
insert
或update
调用更新表。以下是我所做工作的简化示例:
[Person] table:
id | lastname | firstname | city | age
[Person_View] table:
id | lastname | firstname | city
以下是触发器和相关程序:
CREATE TRIGGER tg_update_person_view
INSTEAD OF INSERT OR UPDATE OR DELETE ON
Person_View FOR EACH ROW EXECUTE PROCEDURE update_person_view_table();
如果我这样做:
INSERT INTO Person_View (id, city) VALUES ('3', 'Berlin')
仅具有ID的行将添加到视图和父表中
如何在过程中检查插入值的列是否在过程中定义了“映射”,如果没有任何映射列,则不会继续进行操作?您可以在表上定义检查约束,例如:
create table person(
id int primary key,
lastname text,
firstname text,
city text,
age int,
check(coalesce(lastname, firstname, city, age::text) is not null)
);
insert into person (id)
values (1);
ERROR: new row for relation "person" violates check constraint "person_check"
DETAIL: Failing row contains (1, null, null, null, null).
无论是否创建了基于表的任何视图,该解决方案都有效。您可以在表上定义检查约束,例如:
create table person(
id int primary key,
lastname text,
firstname text,
city text,
age int,
check(coalesce(lastname, firstname, city, age::text) is not null)
);
insert into person (id)
values (1);
ERROR: new row for relation "person" violates check constraint "person_check"
DETAIL: Failing row contains (1, null, null, null, null).
无论是否创建了基于表的任何视图,该解决方案都有效。在删除时为
提供单独的触发器和触发器功能,以简化操作。(您在删除时没有执行任何操作。
)
一个检查约束似乎是个好主意。不过,您不需要合并和铸造。检查行值是否为NULL
CHECK (NOT ROW(lastname, firstname) IS NULL) -- ROW keyword is noise
这将强制行中至少有一个notnull值。适用于任意数量的列和任意数据类型
请特别注意,行(lastname,firstname)不为空
不相同且不起作用。详细说明:
如果检查
约束不是选项,则可以在触发器中使用相同的表达式-这应该比将其添加到触发器函数更快
此外,触发器定义可以指定布尔值WHEN
条件,该条件
将进行测试,以确定是否应触发触发器。在里面
当
条件可以检查旧的和/或新的时,行级触发
行的列的值
如果WHEN
表达式的计算结果不为TRUE
,则触发器函数甚至不会被调用-因此它不会像请求的那样继续执行
但是,我没有击中你的扳机是而不是
而不是
触发器在
条件下不支持
在这种情况下,您必须将支票移动到功能体中:
IF NOT (NEW.lastname, NEW.firstname) IS NULL THEN
-- do stuff
END IF;
在删除时为提供单独的触发器和触发器功能,以简化操作。(您在删除时没有执行任何操作。
)
一个检查约束似乎是个好主意。不过,您不需要合并和铸造。检查行值是否为NULL
CHECK (NOT ROW(lastname, firstname) IS NULL) -- ROW keyword is noise
这将强制行中至少有一个notnull值。适用于任意数量的列和任意数据类型
请特别注意,行(lastname,firstname)不为空
不相同且不起作用。详细说明:
如果检查
约束不是选项,则可以在触发器中使用相同的表达式-这应该比将其添加到触发器函数更快
此外,触发器定义可以指定布尔值WHEN
条件,该条件
将进行测试,以确定是否应触发触发器。在里面
当
条件可以检查旧的和/或新的时,行级触发
行的列的值
如果WHEN
表达式的计算结果不为TRUE
,则触发器函数甚至不会被调用-因此它不会像请求的那样继续执行
但是,我没有击中你的扳机是而不是
而不是
触发器在
条件下不支持
在这种情况下,您必须将支票移动到功能体中:
IF NOT (NEW.lastname, NEW.firstname) IS NULL THEN
-- do stuff
END IF;
在Postgres 9.3+中,您不需要规则或触发器,基于单个表的视图是可自动更新的。我知道,我应该说这个简化的示例是可自动更新的。我的实际情况是,我有基于多个表的视图,我不希望出现这些空记录。在Postgres 9.3+中,您不需要规则或触发器,基于单个表的视图是可自动更新的。我知道,我应该说这个简化的示例是可自动更新的。我的实际情况是,我有基于多个表的视图,我不希望出现这些空记录。我得到以下错误:错误:而不是触发器不能有WHEN条件************错误******
@kaycee:哦,对不起。而不是触发器。在这种情况下,您必须将支票移动到函数中。(您是否考虑过<代码>检查/代码>约束?),我得到这个错误:<代码>错误:而不是触发器,当条件“***********>代码>时,不能有。”而不是触发器。在这种情况下,您必须将支票移动到函数中。(你考虑过<代码>检查/代码>约束吗?)