我不明白为什么PostgreSQL指示一个过程不存在

ippsafx7  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(139)

我有一个奇怪的问题与PostgreSQL.它表明,一个过程不存在,而我认为我创建了它.我真的不明白.我试图删除参数,只是为了看看我是否会有同样的问题或另一个,但我仍然得到了同样的问题.
下面是我的代码:

DROP TABLE IF EXISTS clients, accounts, transactions, failed_transactions CASCADE;

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);

字符串

lx0bsm1f

lx0bsm1f1#

首先,触发器需要调用一个触发器 * 函数 *,而不是一个过程。但是没有什么可以阻止你编写一个PL/pgSQL触发器函数,CALL是你喜欢的过程。
CREATE TRIGGER允许这种语法可能会让人感到困惑:

CREATE TRIGGER ... EXECUTE { PROCEDURE | FUNCTION } ...

字符串
然而,这是PostgreSQL有过程之前遗留下来的语法。当时,唯一允许的语法是EXECUTE PROCEDURE,尽管它调用了触发器函数。随着过程的出现,这变得相当奇怪,所以引入了新的和现在首选的语法EXECUTE FUNCTION,但出于兼容性原因,EXECUTE PROCEDURE仍然允许。尽管如此,您只能调用函数,而不是一个程序。
代码的另一个问题是,您试图在CREATE TRIGGER语句中向触发器函数传递参数。您可以传递参数,但它们必须是字符串常量,并通过触发器函数中的特殊变量TG_ARGV访问(请参阅文档)。您必须定义不带**参数的触发器函数。OLDNEW可用于行级触发器的触发器函数中,而无需显式传递它们。

相关问题