私はこのテーブルを持っています:
CREATE TABLE accounts (
id BIGINT NOT NULL UNIQUE,
balance INTEGER DEFAULT 0
);
そして、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;
しかし、id
をupsert_balance
関数の引数として渡す必要があるため、トリガーコールバックで新しく挿入された値をどのように使用するかわかりません。
どうすればこれを達成できますか?
編集:私はそれを修正しました、アダムの答えのおかげで、誰かがそれを必要とする場合に備えて、これが作業バージョンです:
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();
トリガー関数内では、NEW.column_nameを使用して、新しく挿入または更新された値を参照できます。逆に、OLD.column_nameは、更新/削除前の値を参照します。
詳細はこちら: https://www.postgresql.org/docs/current/static/sql-createtrigger.html
お役に立てば幸いです。
トリガー関数内では、NEW.column_name
を使用して、新しく挿入または更新された値を参照できます。逆に、OLD.column_name
は、更新または削除前の値を参照します。
詳細はこちら: https://www.postgresql.org/docs/current/static/sql-createtrigger.html
お役に立てば幸いです。