假设我在我的数据库(PostgreSQL-9.x)中有两个表:
所以问题是关于函数
如果我在同一个事务中批量插入许多行到
CREATE TABLE FOLDER (
KEY BIGSERIAL PRIMARY KEY,
PATH TEXT,
NAME TEXT
);
CREATE TABLE FOLDERFILE (
FILEID BIGINT,
PATH TEXT,
PATHKEY BIGINT
);
每当我在FOLDERFILE
中插入或更新数据时,我会自动从FOLDER.KEY
更新FOLDERFILE.PATHKEY
:
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();
所以问题是关于函数
folderfile_fill_pathkey()
的易变性。文档说:
但据我所知,这个函数并没有改变它所依赖的表中的任何数据,所以我可以将这个函数标记为任何具有副作用的函数必须标记为易变
IMMUTABLE
。这样做是否正确?如果我在同一个事务中批量插入许多行到
FOLDERFILE
中,是否会对不可变触发器函数造成任何问题?BEGIN;
INSERT INTO FOLDERFILE ( ... );
...
INSERT INTO FOLDERFILE ( ... );
COMMIT;
STABLE
是否实际上表现更好。查询优化取决于许多因素。(在您的情况下,即在函数内不查询触发器的目标表FOLDERFILE
,这应该没有关系)。但是,如果您想要精确,应该使用真实数据测试两种变体。 - pozs