使用postgres 11,我想自动将行从一个表移动到另一个表。我已经设置了一个查询、触发器函数和触发器,但是当触发器启用时,我的测试插入失败,返回“0 0”。
要从中移动行的源表是“cmdb”
要将行移动到的目标表是“cmdb_attic”
条件是当列“mgmt_ip”=时
整行应该移动
该表仅包含3列:“主机名”、“管理ip”、“操作系统类型”
我得到的触发函数代码是:

BEGIN
    WITH moved_rows AS (
        DELETE FROM cmdb
        WHERE mgmt_ip=''
        RETURNING *
    )
    INSERT INTO cmdb_attic
    SELECT * FROM moved_rows;
    RETURN NULL;
END;

我在“cmdb”表下定义了一个触发器,该触发器在事件插入之前触发。
当我对表“cmdb”执行测试插入时,没有收到错误消息,也没有任何内容被插入到任何一个表中。
解决方案
我从pgAdmin中删除了触发器函数和触发器,并将下面提供的代码Bergi运行到pgsql中,它工作正常。
CREATE FUNCTION redirect_to_attic() RETURNS TRIGGER
AS $$
BEGIN
    IF NEW.mgmt_ip = '' THEN
        INSERT INTO cmdb_attic VALUES (NEW.*);
        RETURN NULL;
    ELSE
        RETURN NEW;
    END IF;
END;
$$ LANGUAGE PLPGSQL;
CREATE TRIGGER redirect
  BEFORE INSERT
  ON cmdb
  FOR EACH ROW
  EXECUTE PROCEDURE redirect_to_attic();

编辑1-来自pgsql的触发器详细信息
inv_net=# select * from pg_trigger;
 tgrelid |    tgname     | tgfoid | tgtype | tgenabled | tgisinternal | tgconstrrelid | tgconstrindid | tgconstraint | tgdeferrable | tginitdeferred | tgnargs | tgattr | tgargs | tgqual | tgoldtable | tgnewtable
---------+---------------+--------+--------+-----------+--------------+---------------+---------------+--------------+--------------+----------------+---------+--------+--------+--------+------------+------------
   24623 | move_to_attic |  24618 |      7 | O         | f            |             0 |             0 |            0 | f            | f              |       0 |        | \x     |        |            |
(1 row)

编辑2-测试插入并选择
启动触发器后,我得到的结果如下。如果我禁用触发器,我的insert就可以工作,并且我可以在“cmdb”中找到那一行。
inv_net=# INSERT INTO cmdb(hostname, mgmt_ip, os_type) VALUES ('testdevice', '', 'ios');
INSERT 0 0

inv_net=# select * from cmdb where hostname='testdevice';
 hostname | mgmt_ip | os_type
----------+---------+---------
(0 rows)

inv_net=# select * from cmdb_attic where hostname='testdevice';
 hostname | mgmt_ip | os_type
----------+---------+---------
(0 rows)

编辑3-在pgAdmin4中创建和应用触发器函数和触发器的步骤
未列出的设置/选项卡未调整
表>触发器函数>创建>触发器函数
键入名称“move_to_attic”
代码选项卡:插入代码(来自原始帖子)
未调整其他选项/设置
表>cmdb>触发器>创建>触发器
键入名称“move_to_attic”
“定义”选项卡:已启用触发器(是)、行触发器(是)、触发器函数public.move_to_attic
“事件”选项卡:之前激发,事件插入
代码选项卡:触发器函数中的代码已经存在
SQL选项卡:只是说“-没有更新。”
编辑4-触发器和触发器函数的SQL选项卡上的输出
触发函数(使用Bergi的答案)
-- FUNCTION: public.move_to_attic()

-- DROP FUNCTION public.move_to_attic();

CREATE FUNCTION public.move_to_attic()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$BEGIN
    IF NEW.mgmt_ip='' THEN
        INSERT INTO cmdb_attic SELECT NEW;
        RETURN NULL;
    ELSE
        RETURN NEW;
    END IF;
END;$BODY$;

ALTER FUNCTION public.move_to_attic()
    OWNER TO svc_netops_postgre;

触发器(应用于cmdb)
-- Trigger: move_to_attic

-- DROP TRIGGER move_to_attic ON public.cmdb;

CREATE TRIGGER move_to_attic
    AFTER INSERT
    ON public.cmdb
    FOR EACH ROW
    EXECUTE PROCEDURE public.move_to_attic();

最佳答案

基本上,我想将插入从cmdb重定向到满足该条件的cmdb阁楼
触发函数应该如下所示:

BEGIN
    IF NEW.mgmt_ip = '' THEN
        INSERT INTO cmdb_attic VALUES (NEW.*);
        RETURN NULL;
    ELSE
        RETURN NEW;
    END IF;
END;

online demo

10-06 02:03