“+”处或附近的 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;

你的函数有两个主要错误:

  1. PL/pgSQL 中没有 SET。使用 :=
  2. 完成分配
  3. 变量的 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 中删除的所有主键,使它们可重复用于下一次插入。但是正如您所说的并发事务,它可能不起作用。