“+”处或附近的 Postgresql 语法错误
Postgresql syntax error at or near "+"
我得到了以下 postgresql 函数:
CREATE OR REPLACE FUNCTION insert_address() RETURNS TRIGGER AS
$BODY$
DECLARE row_count INTEGER;
DECLARE max_id INTEGER;
DECLARE key_ INTEGER;
BEGIN
SELECT count(*) FROM ADDRESS INTO row_count;
IF row_count = 0
THEN SET NEW.id_address = 1;
ELSE SELECT count(table_name)
FROM FREE_KEYS
WHERE table_name = 'ADDRESS' INTO row_count;
IF row_count = 0
THEN SELECT max(id_address) FROM ADDRESS INTO max_id;
SET NEW.id_address = max_id + 1;
ELSE SELECT min(free_key) FROM FREE_KEYS WHERE table_name = 'ADDRESS' INTO key_;
SET NEW.id_address = key_;
DELETE FROM FREE_KEYS WHERE table_name = 'ADDRESS' AND free_key = key_;
END IF;
END IF;
END;
$BODY$ LANGUAGE plpgsql;
不明白为什么赋值操作returns出现如下错误:
ERROR: syntax error at or near "+"
LINE 700: SET NEW.id_address = max_id + 1;
你的函数有两个主要错误:
- PL/pgSQL 中没有 SET。使用
:=
完成分配
- 变量的
INTO
子句必须在 SELECT 语句中的列列表之后。
CREATE OR REPLACE FUNCTION insert_address() RETURNS TRIGGER AS
$BODY$
DECLARE row_count INTEGER;
DECLARE max_id INTEGER;
DECLARE key_ INTEGER;
BEGIN
SELECT count(*)
INTO row_count --<< the INTO has to be after the column list
FROM ADDRESS;
IF row_count = 0
THEN
NEW.id_address := 1; --<< there is no SET in PL/pgSQL
ELSE
SELECT count(table_name)
INTO row_count --<< the INTO has to be after the column list
FROM FREE_KEYS
WHERE table_name = 'ADDRESS';
IF row_count = 0
THEN
SELECT max(id_address)
INTO max_id --<< the INTO has to be after the column list
FROM ADDRESS;
NEW.id_address := max_id + 1;
ELSE
SELECT min(free_key)
INTO key_ --<< the INTO has to be after the column list
FROM FREE_KEYS
WHERE table_name = 'ADDRESS';
NEW.id_address := key_;
DELETE FROM FREE_KEYS WHERE table_name = 'ADDRESS' AND free_key = key_;
END IF;
END IF;
END;
$BODY$ LANGUAGE plpgsql;
但最大的问题是功能本身。这在具有多个并发事务的环境中是行不通的。您不能使用 select max()
"generate" 新 ID,除非您为每个插入锁定整个 table,否则它根本无法工作。
感谢您对我有用的帮助。我正在尝试在每个 table 上使用触发器来管理主键。我有一个名为 FREE_KEYS 的 table,它包含从 table 中删除的所有主键,使它们可重复用于下一次插入。但是正如您所说的并发事务,它可能不起作用。
我得到了以下 postgresql 函数:
CREATE OR REPLACE FUNCTION insert_address() RETURNS TRIGGER AS
$BODY$
DECLARE row_count INTEGER;
DECLARE max_id INTEGER;
DECLARE key_ INTEGER;
BEGIN
SELECT count(*) FROM ADDRESS INTO row_count;
IF row_count = 0
THEN SET NEW.id_address = 1;
ELSE SELECT count(table_name)
FROM FREE_KEYS
WHERE table_name = 'ADDRESS' INTO row_count;
IF row_count = 0
THEN SELECT max(id_address) FROM ADDRESS INTO max_id;
SET NEW.id_address = max_id + 1;
ELSE SELECT min(free_key) FROM FREE_KEYS WHERE table_name = 'ADDRESS' INTO key_;
SET NEW.id_address = key_;
DELETE FROM FREE_KEYS WHERE table_name = 'ADDRESS' AND free_key = key_;
END IF;
END IF;
END;
$BODY$ LANGUAGE plpgsql;
不明白为什么赋值操作returns出现如下错误:
ERROR: syntax error at or near "+"
LINE 700: SET NEW.id_address = max_id + 1;
你的函数有两个主要错误:
- PL/pgSQL 中没有 SET。使用
:=
完成分配
- 变量的
INTO
子句必须在 SELECT 语句中的列列表之后。
CREATE OR REPLACE FUNCTION insert_address() RETURNS TRIGGER AS
$BODY$
DECLARE row_count INTEGER;
DECLARE max_id INTEGER;
DECLARE key_ INTEGER;
BEGIN
SELECT count(*)
INTO row_count --<< the INTO has to be after the column list
FROM ADDRESS;
IF row_count = 0
THEN
NEW.id_address := 1; --<< there is no SET in PL/pgSQL
ELSE
SELECT count(table_name)
INTO row_count --<< the INTO has to be after the column list
FROM FREE_KEYS
WHERE table_name = 'ADDRESS';
IF row_count = 0
THEN
SELECT max(id_address)
INTO max_id --<< the INTO has to be after the column list
FROM ADDRESS;
NEW.id_address := max_id + 1;
ELSE
SELECT min(free_key)
INTO key_ --<< the INTO has to be after the column list
FROM FREE_KEYS
WHERE table_name = 'ADDRESS';
NEW.id_address := key_;
DELETE FROM FREE_KEYS WHERE table_name = 'ADDRESS' AND free_key = key_;
END IF;
END IF;
END;
$BODY$ LANGUAGE plpgsql;
但最大的问题是功能本身。这在具有多个并发事务的环境中是行不通的。您不能使用 select max()
"generate" 新 ID,除非您为每个插入锁定整个 table,否则它根本无法工作。
感谢您对我有用的帮助。我正在尝试在每个 table 上使用触发器来管理主键。我有一个名为 FREE_KEYS 的 table,它包含从 table 中删除的所有主键,使它们可重复用于下一次插入。但是正如您所说的并发事务,它可能不起作用。