PGSQL 触发器函数写入日志表异常 [英] PGSQL Trigger Function Write Exception to Log Table

查看:76
本文介绍了PGSQL 触发器函数写入日志表异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

我是 PostgreSQL 的新手,我在使用这个触发器函数时遇到了一些问题,我在下面显然已经大大简化了.我可以要求帮助修复查询,但我认为我可以处理这个问题,我更关心的是我有很多这样的功能,我需要一种方法来了解它失败的原因,哪些失败了.

I'm new to PostgreSQL and I'm having some issues with this trigger function, which I've obviously simplified considerably below. I could ask to help fix the query, but I think I can handle that, and what I'm more concerned about is that I have a lot of functions like this and I need a way to be able to have visibility into why it's failing, and which ones are failing.

问题

我怎样才能捕获在这个函数中发生的异常并将它们写入某种日志表,以便我可以查看和修复每个异常?理想情况下,我也想将失败的 sql 语句写入日志表,以便我可以具体查看出了什么问题.我看过一些类似的例子,但它们似乎不适合我的场景.

How can I catch exceptions that happen within this function and write them to some kind of log table so I can review and fix each one? Ideally I'd like to write the sql statement that failed to the log table as well so I can see specifically what went wrong. I've seen a few examples of similar things, but they don't seem to fit my scenario.

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;

推荐答案

这是一个例子,使用普通函数而不是触发器,尽管就如何登录而言,这实际上是相同的:

Here's an example, using a normal function rather than a trigger, though it's really the same thing in as far as how to log:

存储错误的表:

CREATE TABLE errors (id SERIAL, sql_state TEXT, message TEXT, detail TEXT, hint TEXT, context TEXT);

运行并具有异常处理/日志记录的函数:

Function which does work and has the exception handling/logging:

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表包含:

After calling the function, the errors table contains:

请参阅 https://rextester.com/BQPG27732

上下文显示了各种调用堆栈.当然,您可以添加更多与错误相关的字段,我只选择了 GET STACKED DIAGNOSTICS

Context shows a call stack of sorts. You could add more error-related fields of course, I only chose a handful of those available in GET STACKED DIAGNOSTICS

这篇关于PGSQL 触发器函数写入日志表异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆