Postgres RAISE EXCEPTION 不会中止函数执行

Postgres RAISE EXCEPTION does not abort function execution

提问人:Igor Shmukler 提问时间:11/2/2022 更新时间:11/2/2022 访问量:245

问:

我写了下面的函数:

CREATE OR REPLACE FUNCTION process_init_transfer(
  holder_email TEXT,
  order_key BIGINT, ticket_key BIGINT,
  email_address TEXT,
  first_name TEXT, last_name TEXT
) RETURNS TEXT AS $$
  DECLARE
    _id BIGINT;
    _token TEXT;
    _title TEXT;
    _tickets_count INTEGER;
    _transfers_count INTEGER;
  BEGIN
    SELECT
      COUNT(*), events.name
    INTO
      _tickets_count, _title
    FROM
      tickets, purchases, ticket_books, events
    WHERE
      purchases.email = holder_email AND
      purchases.id = order_key AND
      tickets.order_id = purchases.id AND
      tickets.id = ticket_key AND
      ticket_books.id = tickets.book_id AND
      events.id = ticket_books.event_id
    GROUP BY
      events.name;
    IF _tickets_count <> 1 THEN
      RAISE EXCEPTION 'Error finding your ticket, contact support';
    END IF;
    SELECT
      COUNT(*)
    INTO
      _transfers_count
    FROM
      ticket_transfers
    WHERE
      ticket_id = ticket_key AND
      (status = 'PENDING' OR status = 'ACCEPTED' OR status = 'CONFIRMED');
    IF _transfers_count > 0 THEN
      RAISE EXCEPTION 'Ticket already transfered, contact support if you believe this is an error';
    END IF;

    INSERT INTO
      ticket_transfers (ticket_id, email, name, surname, token)
    VALUES
      (ticket_key, email_address, first_name, last_name, random_string(16))
    RETURNING
      token INTO _token;

    INSERT INTO
      emails (payload, template_id)
    VALUES
      (json_build_object('recipient', holder_email, 'ticket', ticket_key,
        'email', holder_email, 'title', _title, 'token', _token), 7)
    RETURNING
      id INTO _id;
    RETURN _id;
  END;
$$ LANGUAGE plpgsql;

在一些情况下,该函数会引发异常。我理解了文档,这应该中止函数执行。然而,我不相信这就是正在发生的事情。

我看到以下错误:。这意味着,尽管存在异常,但执行仍会达到: 。这不应该发生。 我希望以下内容会停止执行insert or update on table "ticket_transfers" violates foreign key constraintINSERT INTO ticket_transfers

IF _tickets_count <> 1 THEN
  RAISE EXCEPTION 'Error finding your ticket, contact support';
END IF;

请指教!

SQL PostgreSQL 异常 存储过程

评论

2赞 Frank Heikens 11/2/2022
使用 RAISE INFO 获取 _tickets_count 和 _transfers_count 的值,我们现在只能猜测

答:

1赞 Laurenz Albe 11/2/2022 #1

第一个可能设置为 NULL,因为查询不返回任何行。由于不是 TRUE,因此不会触发错误。SELECT_tickets_countNULL <> 1