我在使用 PostgreSQL 时遇到了一个奇怪的问题。它表明一个过程不存在,而我认为是我创建的。我实在是不明白。我尝试删除参数只是为了看看我是否会遇到相同的问题或另一个问题,但我仍然遇到相同的问题......
这是我的代码:
DROP TABLE IF EXISTS clients, accounts, transactions, failed_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 >= -500)
);
CREATE TABLE IF NOT EXISTS transactions
(
id serial PRIMARY KEY,
amount float
);
CREATE TABLE failed_transactions
(
id serial,
account_id integer,
attempted_amount float,
timestamp timestamp DEFAULT NOW()
);
CREATE OR REPLACE PROCEDURE log_failed_transaction(new_line record, old_line record)
LANGUAGE plpgsql
AS $$
BEGIN
IF new_line.balance<-500 THEN
INSERT INTO failed_transactions(account_id, attempted_amount)
VALUES (new_line.id, new_line.balance-old_line.balance);
END IF;
END $$;
CREATE OR REPLACE TRIGGER accounts_update BEFORE UPDATE ON accounts
FOR EACH STATEMENT
EXECUTE PROCEDURE log_failed_transaction(NEW, OLD);
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 (8, 2000, 14);
INSERT INTO accounts VALUES (12, 650, 10);
INSERT INTO accounts VALUES (2, 300, 25);
不,触发器需要调用触发器函数,而不是过程。但是没有什么可以阻止您编写 PL/pgSQL 触发器函数,
CALL
是您喜欢的过程。
CREATE TRIGGER
允许这种语法可能会令人困惑:
CREATE TRIGGER ... EXECUTE { PROCEDURE | FUNCTION } ...
然而,这是 PostgreSQL 有过程之前的语法遗留物。当时,唯一允许的语法是
EXECUTE PROCEDURE
,即使它调用了触发器函数。随着过程的出现,这变得相当奇怪,因此引入了新的且现在首选的语法 EXECUTE FUNCTION
,但出于兼容性原因仍然允许使用 EXECUTE PROCEDURE
。不过,您只能调用函数,而不能调用过程。