Postgres - 将行移动到不同的 table
Postgres - move rows to different table
使用 postgres 11 我想自动将行从一个 table 移动到另一个。我已经设置了查询、触发器函数和触发器,但是当启用触发器时,我的测试插入失败并显示“0 0”。
- 源 table 要移动的行来自 'cmdb'
- 要将行移动到的目标 table 是 'cmdb_attic'
- 条件是当列 'mgmt_ip' = ''
- 整行都应该移动
- table 只包含 3 列:'hostname'、'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;
我在 table 'cmdb' 下定义了一个触发器,它在插入事件之前触发。
当我针对 table 'cmdb' 进行测试插入时,我没有收到任何错误消息,也没有插入任何内容 - table.
解决方案
我从 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 - 测试插入和 select
启用触发器后,下面是我得到的结果。如果我禁用触发器,我的插入工作,我可以在 '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 中创建和应用触发器函数和触发器的步骤
settings/tabs未列出未调整
- 表 > 触发函数 > 创建 > 触发函数
- 类型名称'move_to_attic'
- 代码选项卡:插入代码(来自原始 post)
- 没有其他options/settings调整
- 表 > 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();
basically I want to redirect an insert from cmdb to cmdb_attic where that condition is met
触发函数应该如下所示:
BEGIN
IF NEW.mgmt_ip = '' THEN
INSERT INTO cmdb_attic VALUES (NEW.*);
RETURN NULL;
ELSE
RETURN NEW;
END IF;
END;
使用 postgres 11 我想自动将行从一个 table 移动到另一个。我已经设置了查询、触发器函数和触发器,但是当启用触发器时,我的测试插入失败并显示“0 0”。
- 源 table 要移动的行来自 'cmdb'
- 要将行移动到的目标 table 是 'cmdb_attic'
- 条件是当列 'mgmt_ip' = ''
- 整行都应该移动
- table 只包含 3 列:'hostname'、'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;
我在 table 'cmdb' 下定义了一个触发器,它在插入事件之前触发。
当我针对 table 'cmdb' 进行测试插入时,我没有收到任何错误消息,也没有插入任何内容 - table.
解决方案
我从 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 - 测试插入和 select
启用触发器后,下面是我得到的结果。如果我禁用触发器,我的插入工作,我可以在 '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 中创建和应用触发器函数和触发器的步骤
settings/tabs未列出未调整
- 表 > 触发函数 > 创建 > 触发函数
- 类型名称'move_to_attic'
- 代码选项卡:插入代码(来自原始 post)
- 没有其他options/settings调整
- 表 > 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();
basically I want to redirect an insert from cmdb to cmdb_attic where that condition is met
触发函数应该如下所示:
BEGIN
IF NEW.mgmt_ip = '' THEN
INSERT INTO cmdb_attic VALUES (NEW.*);
RETURN NULL;
ELSE
RETURN NEW;
END IF;
END;