Postgres-将行移动到其他表

时间:2019-11-14 23:46:00

标签: postgresql postgresql-triggers

使用postgres 11我想自动将行从一个表移动到另一个表。我已经设置了查询,触发器功能和触发器,但是启用触发器后,我的测试插入失败并显示为“ 0 0”。

  • 要从中移动行的源表是“ cmdb”
  • 将行移至的目标表是'cmdb_attic'
  • 条件是当列'mgmt_ip'=''
  • 整个行应移动
  • 该表仅包含3列:“主机名”,“ mgmt_ip”,“ os_type”

我拥有的触发功能代码是:

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 -测试插入并选择

启用触发器后,我将获得以下信息。如果禁用触发器,则插入有效,并且可以在“ 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中触发的步骤

未列出的设置/标签未进行调整

  1. 表>触发函数>创建>触发函数
  2. 类型名称“ move_to_attic”
  3. “代码”标签:插入代码(来自原始帖子)
  4. 未调整其他选项/设置
  5. 表> cmdb>触发器>创建>触发器
  6. 类型名称“ move_to_attic”
  7. “定义”选项卡:“已启用触发器”(yes),“行触发器”(yes),触发器功能public.move_to_attic
  8. “事件”标签:先触发,然后插入事件
  9. “代码”标签:我的“触发功能”代码已经存在
  10. “ 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();

1 个答案:

答案 0 :(得分:1)

  

基本上我想将插入内容从cmdb重定向到满足该条件的cmdb_attic

该触发器的功能应如下所示:

agent

online demo