PostgreSQL 8.2:要求 UPDATE 语句中存在特定列
我想强制用户指定某个表(sometbl)的更新来源, 例如。指定“本地”或“远程”(对于 col2) - 但在执行 UPDATE 语句时应在数据库级别检查该要求,因此:
UPDATE sometbl SET col1 = 'abc';
应该抛出错误(异常),但是:
UPDATE sometbl SET col1 = 'abc', col2 = 'remote';
...会成功的。
我尝试为该表创建 BEFORE update 触发器,但我无法检查是否 NEW.col2 已明确设置。
我使用了条件
IF NEW.col2 IS NULL THEN
RAISE EXCEPTION 'you must specify source of this update (local/remote)'
END IF;
,但每次当更新中未指定 col2 (UPDATE sometbl SET col1 = 'abc') 时,
我都会在 NEW.col2 伪变量中获得该字段的当前值,而不是假定的 NULL。
当 UPDATE stmt 中不存在指定字段时,是否有任何解决方法可以阻止 UPDATING 行?
I would like to force user to specify origin of update to some table (sometbl),
eg. to specify 'local' or 'remote' (for col2) - but checking of that requirement should occur at DB level when UPDATE
statement is executed so:
UPDATE sometbl SET col1 = 'abc';
should throw error (exception), but:
UPDATE sometbl SET col1 = 'abc', col2 = 'remote';
...will succeed.
I tried to create BEFORE update trigger for that table, but I was unable to check if
NEW.col2 was explictly set.
I used condition
IF NEW.col2 IS NULL THEN
RAISE EXCEPTION 'you must specify source of this update (local/remote)'
END IF;
but every time, when col2 was not specified in update (UPDATE sometbl SET col1 = 'abc')
I got current value of that field in NEW.col2 pseudo-var, instead of supposed NULL.
Is there any workaround to prevent UPDATING row when specified field is not present in UPDATE stmt?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我将使用一个
安全定义器
函数,该函数由除管理员和/或表所有者之外的唯一用户拥有,该用户对sometbl
具有更新权限。像这样的事情:
但是要小心 安全定义器功能安全。
I'd use a
security definer
function, owned by the only user besides admin and/or table owner, that has update privilege onsometbl
.Something like this:
But be careful about security definer functions security.
几个触发器怎么样?其中一个在更新之前运行,并将该列设置为空。如果列仍然为空,则在更新后运行并进行 pukes(返回 NULL)。 (如果触发器返回 NULL,则更新失败。)
How about a couple of triggers? One runs before the update, and sets the column to null. One runs after the update and pukes (returns NULL) if the column is still null. (If a trigger returns NULL, the update fails.)
您可以创建第二个表,其中包含具有 ID 值的本地和远程条目,然后只需在第一个表中使用该表的非空外键。
You could create a second table that contains your local and remote entries with an ID value, then simply use a not-null foreign key to that table in the first table.
您可以创建几个存储过程,例如
You could create a couple of stored procedures, a la
好的,阅读文档并尝试后,我可以报告 BEFORE 触发器是可行的方法。触发器提供绑定到新元组和旧元组的名称 NEW 和 OLD。从 BEFORE 触发器返回 NULL 会阻止更新。因此:
OK, having read the docs and tried it out, I can report that a BEFORE trigger is the way to go. A trigger provides the names NEW and OLD bound to the new and former tuples. Returning NULL from a BEFORE trigger prevents the update. Hence: