gpt4 book ai didi

postgresql - 在 PL/pgsql 中使用 EXECUTE 从通用触发器插入 NEW.*

转载 作者:行者123 更新时间:2023-11-29 11:11:37 28 4
gpt4 key购买 nike

我有许多使用 Postgres“分区”功能的表。我想在每个表上定义一个通用的 BEFORE INSERT OF ROW 触发器,它将 1) 在对父表进行插入时动态创建分区,以及 2) 对分区重新执行插入。

类似于:

CREATE OR REPLACE FUNCTION partition_insert_redirect( )
RETURNS trigger AS $BODY$
BEGIN
... create the new partition and set up the redirect Rules ...

/* Redo the INSERT dynamically. The new RULE will redirect it to the child table */
EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
' SELECT NEW.*'
END

但是"new"记录在 EXECUTE SQL 中是不可见的。我怎样才能使这项工作尽可能简单?

作为替代方案,我能否以某种方式遍历新记录中的字段?

我想过使用临时表:

EXECUTE 'CREATE TEMPORARY TABLE new_row (LIKE ' ||
quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
') ON COMMIT DROP';

INSERT INTO new_row SELECT NEW.*;

EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
' SELECT * FROM new_row';
DROP TABLE new_row;

但这也不起作用,因为缓存了对临时表的引用:Why do I get "relation with OID ##### does not exist" errors when accessing temporary tables in PL/PgSQL functions?

我正在使用 Postgres 8.2,我无法更改为任何其他版本。

编辑:
正如@alvherre 指出的那样,这可能可以在 Postgres 8.4 中使用 EXECUTE ... USING 语法完成。在 http://wiki.postgresql.org/wiki/PL/pgSQL_Dynamic_Triggers 查看示例

最佳答案

您可以使用 EXECUTE USING 将 NEW 传递给它。你的例子是

EXECUTE 'INSERT INTO ' || TG_RELID || '::regclass SELECT $1' USING NEW;

(请注意,我使用转换为 regclass 的 TG_RELID 而不是摆弄 TG_TABLE_SCHEMA 和 TABLE_NAME,因为如果非标准,它更易于使用。但是,plpgsql 无论如何都是非标准的。)

关于postgresql - 在 PL/pgsql 中使用 EXECUTE 从通用触发器插入 NEW.*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1997337/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com