Postgresql 在另一个表上插入失败时保存数据的触发器?

Postgresql 在另一个表上插入失败时保存数据的触发器?,postgresql,plpgsql,Postgresql,Plpgsql,我在谷歌上搜索了一段时间,没有找到这个问题的答案 考虑到这一点,我有一个表test\u表(id序列号,名称varchar(15),姓氏varchar(40))。如果有人试图在名称列中插入大于15个字符的值,它将返回权限被拒绝 我需要知道的是,如果有一种方法可以创建一个触发器,只要未能在测试表上插入,它就会将(插入)所有“丢失”的数据保存在另一个表中(可能类似于)日志插入失败(失败的ID int、失败的姓名文本、失败的姓氏文本) 请不要回答“只是增加列限制”之类的问题,因为这只是一个例子。我需要知

我在谷歌上搜索了一段时间,没有找到这个问题的答案

考虑到这一点,我有一个表
test\u表(id序列号,名称varchar(15),姓氏varchar(40))
。如果有人试图
名称
列中插入大于15个字符的值
,它将返回权限被拒绝

我需要知道的是,如果有一种方法可以创建一个
触发器
,只要未能在
测试表
上插入
,它就会将(插入)所有“丢失”的数据保存在另一个表中(可能类似于)
日志插入失败(失败的ID int、失败的姓名文本、失败的姓氏文本)

请不要回答“只是增加列限制”之类的问题,因为这只是一个例子。我需要知道是否有办法在失败的INSERT命令上记录数据


编辑:只是为了更清楚,因为上面的句子还不够。无论插入时发生什么错误,例如“无效数据类型”、“长度太大”、“您没有插入权限”(可能不是最后一个),我想记录有人试图插入值X,Y,Z在表
test_table
上,它失败了

这里最好的解决方案是编写一个函数,该函数在
插入过程中捕获任何错误
并执行替代方法:

CREATE OR REPLACE FUNCTION do_insert(p_name text, p_surname text) RETURNS void
   LANGUAGE plpgsql AS
$$BEGIN
   INSERT INTO testtable (name, surname)
      VALUES (p_name, p_surname);
EXCEPTION
   WHEN OTHERS THEN
      INSERT INTO log_failed_inserts(failedname, failedsurname)
         VALUES (p_name, p_surname);
END;$$;
如果不需要函数,可以使用
DO
语句:

DO
$$BEGIN
   INSERT ...
EXCEPTION
   WHEN OTHERS THEN
      INSERT ...
END;$$;
这样做的缺点是无法向其传递参数

第三种解决方案是在SQL中显式使用保存点:

BEGIN;
SAVEPOINT sp1;
INSERT INTO test_table ...;
如果没有错误,请继续

COMMIT;
如果出现错误:

ROLLBACK TO SAVEPOINT sp1;
INSERT INTO log_failed_inserts ...;
COMMIT;

是的,只需创建一个触发器函数,如果长度(NEW.“name”)>15,则插入日志\u失败\u插入选择新建。。。返回null并在运行fn()的表上创建一个触发器。伙计们,你看不到这一点。。。字符限制只是一个例子,甚至是错误,不管错误是“权限被拒绝”还是“值太长”。。。我想要一个触发器,它将记录所有值,无论插入时发生什么错误,包括访问权限、长度、错误的参数类型。。。我会把它写在表格上question@VaoTsun:那不行。长度检查是在触发器执行之前完成的。我认为您无法将其写入表中。但您可以将Postgres配置为将所有失败的语句记录到Postgres日志文件中。@a_horse_,带有_no_name yes-true。那么也许是规则?。这是一种方法,但是真正做的
INSERT
是一个java应用程序:/你没有这么说。我添加了更多的解决方案,其中一个应该适用于您。@LaurenzAlbe那么这不可能通过触发器实现吗?我之所以对通过触发器执行此操作感兴趣,是因为如果有人错误地直接在表上运行insert命令,而没有运行do_insert函数,它仍然会在log_failed_inserts.No中添加一行,因为在调用触发器之前会先检查长度。