在 PostgreSQL 的触发器函数中使用新插入的值

ser*_*off 6 postgresql trigger functions

我有这张表:

CREATE TABLE accounts (
  id BIGINT NOT NULL UNIQUE,
  balance INTEGER DEFAULT 0
);
Run Code Online (Sandbox Code Playgroud)

我需要在将行插入 2 个不同的表后更新每个用户的余额,transfers并且deposits.

我创建了 2 个函数来计算新用户余额并更新它:

/* function for getting user balance */
CREATE FUNCTION get_balance(bigint) RETURNS bigint
    AS 'SELECT (
  SELECT COALESCE(sum(CASE WHEN won THEN amount * (multiplier - 1) ELSE -amount END), 0)
  FROM transfers
  WHERE user_id = $1
) + (
  SELECT COALESCE(sum(amount), 0)
  FROM deposits
  WHERE user_id = $1
) as sum;'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;

/* function for updating user balance */
CREATE FUNCTION upsert_balance(bigint) RETURNS VOID
    AS 'INSERT INTO ACCOUNTS (id, balance)
    VALUES ($1, get_balance($1))
  ON CONFLICT (id) DO
  UPDATE SET balance = get_balance($1);'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;
Run Code Online (Sandbox Code Playgroud)

但我不确定如何在触发器回调中使用新插入的值,因为我需要将其id作为参数传递给upsert_balance函数。

我怎样才能做到这一点?

编辑:我修复了它,感谢 Adam 的回答,这是工作版本,以防有人需要它:

CREATE FUNCTION upsert_balance() RETURNS trigger AS $trigger_bound$
BEGIN
    INSERT INTO ACCOUNTS (id, balance)
    VALUES (NEW.user_id, get_balance(NEW.user_id))
    ON CONFLICT (id) DO
    UPDATE SET balance = get_balance(NEW.user_id);

    RETURN NEW;
END;
$trigger_bound$
LANGUAGE plpgsql;

CREATE TRIGGER update_balance_on_inserting_transfer
AFTER INSERT OR UPDATE ON transfers
FOR EACH ROW
EXECUTE PROCEDURE upsert_balance();
Run Code Online (Sandbox Code Playgroud)

小智 6

在触发器函数中,您可以使用 NEW.column_name 来引用新插入/更新的值。相反,OLD.column_name 将引用更新/删除之前的值。

更多信息在这里: https: //www.postgresql.org/docs/current/static/sql-createtrigger.html

希望有帮助。