INSERT在另一个表上失败时触发保存数据?

时间:2017-03-21 14:00:34

标签: postgresql plpgsql

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

考虑一下,我有一个表test_table(id serial, name varchar(15), surname varchar(40))。如果有人在name列中尝试插入超过15个字符的值,则会返回权限被拒绝

我需要知道的是,如果有一种方法可以创建trigger,只要无法在test_table上插入,它就会保存(插入)另一个表中的所有“丢失”数据(可能像)log_failed_inserts(failedid int, failedname text, failedsurname text)

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

编辑:为了更清楚,因为上面的句子还不够。无论插入时出现什么错误,“无效数据类型”,“长度太大”,“你没有插入权限”(也许不是最后一个),我想记录某事/有人试图在表test_table上插入值X,Y,Z,然后失败

1 个答案:

答案 0 :(得分:0)

这里最好的解决方案是编写一个能够在INSERT期间捕获任何错误并执行替代方案的函数:

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;