如何纠正我的PostgreSQL,以纠正语法错误,并很好地使用CREATE TRIGGER语句?

xyhw6mcr  于 2023-10-18  发布在  PostgreSQL
关注(0)|答案(2)|浏览(128)

我需要创建一个PostgreSQL PL/pgSQL代码,能够模拟从一个帐户到另一个帐户的简单转账。下面是我的代码:

DROP TABLE clients, accounts, transactions;
 
CREATE TABLE IF NOT EXISTS clients
(
    id int PRIMARY KEY,
    name varchar
);
 
CREATE TABLE IF NOT EXISTS accounts
(
    id int PRIMARY KEY,
    balance float,
    client int,
    FOREIGN KEY (client) REFERENCES clients(id),
    CHECK (balance >= 0)
);
 
CREATE TABLE IF NOT EXISTS transactions
(
    id int PRIMARY KEY,
    payer int,
    recipient int,
    amount float,
    FOREIGN KEY (payer) REFERENCES clients(id),
    FOREIGN KEY (recipient) REFERENCES clients(id)
);
 
 
INSERT INTO clients VALUES (10, 'Client 1');
INSERT INTO clients VALUES (14, 'Client 2');
INSERT INTO clients VALUES (25, 'Client 3');
 
INSERT INTO accounts VALUES (2, 300, 10);
INSERT INTO accounts VALUES (8, 2000, 14);
INSERT INTO accounts VALUES (12, 650, 25);
 
 
 
 
CREATE TRIGGER new_transaction
AFTER INSERT ON transactions
BEGIN
    UPDATE accounts
    SET balance = balance - 50
    FROM clients
    WHERE clients.id = accounts.client AND clients.id = 10;
    UPDATE accounts
    SET balance = balance + 50
    FROM clients
    WHERE clients.id = accounts.client AND clients.id = 14;
END;
 
 
 
 
INSERT INTO transactions VALUES (1, 10, 14, 50);
SELECT * FROM accounts;

但语法错误使其无法工作...我试着不使用开始和END,而是使用“FOR EACH STATEMENT”,但它也犯了一个语法错误。你能帮帮我吗?
提前感谢您的回答!

esbemjvw

esbemjvw1#

你需要创建一个函数来触发它;

CREATE OR REPLACE FUNCTION update_account_balance()
RETURNS TRIGGER AS $$
BEGIN
    -- amount from the payer's balance
    UPDATE accounts
    SET balance = balance - NEW.amount
    WHERE client = NEW.payer;

    -- amount to the recipient's balance
    UPDATE accounts
    SET balance = balance + NEW.amount
    WHERE client = NEW.recipient;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

然后通过

CREATE TRIGGER new_transaction
AFTER INSERT ON transactions
FOR EACH ROW
EXECUTE FUNCTION update_account_balance();

继续您的事务,它将自动触发事务表中的每个行插入。

wpcxdonn

wpcxdonn2#

让我们把你目前的代码错误放在一边,讨论一下设计。根据目前的结构,如果您引入 * 一个客户只能有一个帐户 * 的规则,您的设计就可以工作。为什么?每个transactions条目都绕过accounts表,直接进入clients,然后为客户端获取accounts-所有客户端帐户。这反过来又会导致transactions影响每个付款人和收款人的交易中的所有帐户。Example Here。250的1次传输结果。
1.客户100余额增加250。正确.
1.客户端200余额减少500。应减少250
1.所有余额总计减少250。应该保持不变。
解决方案:不要将transactionsclients关联,而是将它们与单个accounts关联。例如:

CREATE TABLE IF NOT EXISTS transactions
(
    id int PRIMARY KEY,
    payer_account int,
    recipient_account int,
    amount float,
    FOREIGN KEY (payer_account) REFERENCES accounts(id),
    FOREIGN KEY (recipient_account) REFERENCES accounts(id)
);

或者,在accounts表中对client放置一个唯一约束。从而将客户限制在一个帐户内。

相关问题