2ca*_*can 4 postgresql volatile immutability volatility
假设我的DB(postgresql-9.x)中有2个表
CREATE TABLE FOLDER (
KEY BIGSERIAL PRIMARY KEY,
PATH TEXT,
NAME TEXT
);
CREATE TABLE FOLDERFILE (
FILEID BIGINT,
PATH TEXT,
PATHKEY BIGINT
);
Run Code Online (Sandbox Code Playgroud)
我自动更新FOLDERFILE.PATHKEY来自FOLDER.KEY每当我插入或更新FOLDERFILE:
CREATE OR REPLACE FUNCTION folderfile_fill_pathkey() RETURNS trigger AS $$
DECLARE
pathkey bigint;
changed boolean;
BEGIN
IF tg_op = 'INSERT' THEN
changed := TRUE;
ELSE IF old.FILEID != new.FILEID THEN
changed := TRUE;
END IF;
END IF;
IF changed THEN
SELECT INTO pathkey key FROM FOLDER WHERE PATH = new.path;
IF FOUND THEN
new.pathkey = pathkey;
ELSE
new.pathkey = NULL;
END IF;
END IF;
RETURN new;
END
$$ LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER folderfile_fill_pathkey_trigger AFTER INSERT OR UPDATE
ON FOLDERFILE FOR EACH ROW EXECUTE PROCEDURE fcliplink_fill_pathkey();
Run Code Online (Sandbox Code Playgroud)
因此,问题在于功能的folderfile_fill_pathkey()波动性。文件说
任何具有副作用的功能都必须标记为VOLATILE
但是据我了解–该函数不会更改它依赖的表中的任何数据,因此我可以将该函数标记为IMMUTABLE。正确吗?
如果我将多个行批量插入FOLDERFILE同一事务中,则IMMUTABLE触发功能是否会出现任何问题,例如:
BEGIN;
INSERT INTO FOLDERFILE ( ... );
...
INSERT INTO FOLDERFILE ( ... );
COMMIT;
Run Code Online (Sandbox Code Playgroud)
首先,正如@pozs已经指出的那样,您提供的函数定义绝对是肯定的,STABLE而不是IMMUTABLE因为它执行数据库查找。这意味着结果不只是从输入参数中得出(正如IMMUTABLE所建议的那样),而且还从存储在FOLDER表中的数据中得到(必然会发生变化)。根据文档:
STABLE表示该函数无法修改数据库,并且在单个表扫描中它将针对相同的参数值一致地返回相同的结果,但其结果可能会在SQL语句之间发生变化。对于 其结果取决于数据库查找,参数变量(例如当前时区)等的函数,这是适当的选择。
其次,在触发器函数中添加稳定性修饰符(IMMUTABLE/ STABLE/ VOLATILE)最多只能起到说明作用,因为AFAIK PostgreSQL实际上并未执行任何保证使用它们的计划。在下面的帖子从pgsql-hackers邮件列表似乎支持我的要求:
无论如何,对于触发器功能,波动率是完全不可操作的,因为成本/行等其他计划程序参数也是如此,因为触发器调用中没有计划。
综上所述:您最好暂时避免在trigger(!)过程中使用稳定性关键字,因为将它们包括在内似乎并没有带来什么好处,但会带来一些意想不到的警告/陷阱(请参阅@pozs第一个注释的结尾) )。
| 归档时间: |
|
| 查看次数: |
1383 次 |
| 最近记录: |