背景
我是PostgreSQL的新手,并且此触发函数存在一些问题,下面将对我进行明显的简化。我可以要求帮助解决该查询,但是我想我可以解决这个问题,而我更担心的是,我有很多类似的功能,并且我需要一种方法来了解其失败原因,哪些失败了。
问题
如何捕获此函数中发生的异常并将它们写入某种日志表,以便我可以检查并修复每个异常?理想情况下,我也想将失败的sql语句写到日志表中,这样我就可以具体查看出了什么问题。我已经看到了一些类似情况的示例,但它们似乎与我的情况不符。
CREATE OR REPLACE FUNCTION my_func() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'INSERT') THEN
INSERT INTO my_table(...)
SELECT ...
FROM table_1 t1
JOIN table_2 t2 ON t1.id = t2.id
ON CONFLICT (id)
DO UPDATE
field1 = EXCLUDED.field1;
ELSIF(TG_OP = 'UPDATE') THEN
UPDATE my_table
SET ...
FROM table_1 t1
JOIN table_2 t2 ON t1.id = t2.id
WHERE id = NEW.id;
ELSIF (TG_OP = 'DELETE') THEN
DELETE FROM my_table WHERE id= OLD.id;
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
答案 0 :(得分:1)
这是一个使用普通函数而不是触发器的示例,尽管就如何记录而言这实际上是相同的:
要存储错误的表:
CREATE TABLE errors (id SERIAL, sql_state TEXT, message TEXT, detail TEXT, hint TEXT, context TEXT);
该功能有效并且具有异常处理/记录功能:
CREATE OR REPLACE FUNCTION my_func()
RETURNS VOID AS
$BODY$
DECLARE
_sql_state TEXT;
_message TEXT;
_detail TEXT;
_hint TEXT;
_context TEXT;
BEGIN
PERFORM 1 / 0;
EXCEPTION
WHEN OTHERS THEN
GET STACKED DIAGNOSTICS
_sql_state := RETURNED_SQLSTATE,
_message := MESSAGE_TEXT,
_detail := PG_EXCEPTION_DETAIL,
_hint := PG_EXCEPTION_HINT,
_context := PG_EXCEPTION_CONTEXT;
INSERT INTO errors (sql_state, message, detail, hint, context)
VALUES (_sql_state, _message, _detail, _hint, _context);
END
$BODY$
LANGUAGE plpgsql;
调用函数后,errors
表包含:
请参见https://rextester.com/BQPG27732
上下文显示了各种调用堆栈。当然,您可以添加更多与错误相关的字段,我只选择了GET STACKED DIAGNOSTICS