我的PostgreSQL 16.1数据库中有一个运行在Debian 12.2上的函数:

CREATE OR REPLACE FUNCTION ref.lookup_xxx(
    in_code character varying,
    in_description character varying)
    RETURNS integer
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE PARALLEL UNSAFE
AS $BODY$
  declare id_val integer;
  begin
    if in_code is null then -- nothing to do
      return null;
    end if;
    -- check if code is already present in the table:
    id_val = (select min(id) from ref.xxx where code = in_code);
    if id_val is null then -- insert new code, desc into reference table:
      insert into ref.xxx (code, description) values (in_code, in_description) returning id_val;
    end if;
    return id_val; -- return id of new or existing row
  exception
    when others then
      raise exception 'lookup_xxx error code, desc = %, %', in_code, in_description;
  end; 
$BODY$;

它返回一个错误:

ERROR:  lookup_xxx error code, desc = 966501, <NULL>
CONTEXT:  PL/pgSQL function ref.lookup_xxx(character varying,character varying) line 15 at RAISE 

SQL state: P0001

如果我运行下面的特殊查询,它会成功:

insert into ref.xxx (code, description) values ('966501', null);

我无法运行此即席查询-它可能无法运行:

do $$
declare x integer;
begin
  insert into ref.xxx (code, description) values ('966501', null) returning x;
  raise notice 'x is %', x;
end; 
$$

我正在寻找任何建议来纠正这个功能-我已经判断了Postgres文档,但没有找到任何有用的东西.单步执行调试器中的函数会显示它在INSERT语句中失败.我在其他plpgsql函数中也有类似的查询,它们工作正常.

推荐答案

看起来你需要这个:返回id到id_val;

CREATE OR REPLACE FUNCTION ref.lookup_xxx(
    in_code CHARACTER VARYING,
    in_description CHARACTER VARYING)
    RETURNS INTEGER
    LANGUAGE 'plpgsql'
    COST 10
    VOLATILE PARALLEL UNSAFE
AS
$BODY$
DECLARE
    id_val INTEGER;
BEGIN
    IF in_code IS NULL THEN -- nothing to do
        RETURN NULL;
    END IF;
    -- check if code is already present in the table:
    id_val = (SELECT MIN(id) FROM ref.xxx WHERE code = in_code);
    IF id_val IS NULL THEN -- insert new code, desc into reference table:
        INSERT INTO ref.xxx (code, description) 
        VALUES (in_code, in_description) 
        RETURNING id 
            INTO id_val; -- <-- this one
    END IF;
    RETURN id_val; -- return id of new or existing row
EXCEPTION -- Why? You will be hiding the real error
    WHEN OTHERS THEN
        RAISE EXCEPTION 'lookup_xxx error code, desc = %, %', in_code, in_description;
END;
$BODY$;

Postgresql相关问答推荐

更新带有视图的表并在关系员工的规则中检测到无限的回归"

在Ubuntu 18.04 Bionic上安装PostgreSQL(已删除回购)

列不明确

让Docker Compose Container等待容器PostgreSQL并恢复

如何在docker-compose中使用docker secrets设置ConnectionString?

为什么这里的默认格式不同? (ISO 8601 的两种不同实现)

查找列中的数据是否满足sql中的数据类型条件

Regexp_replace 行为会改变,如果它用空白字符串或 null 替换字符串数组中的字符串

PostgreSQL unnest 与空数组

在执行 postgresql 函数时提交事务

在 postgres 中删除所有共享相同前缀的表

knex: Select 特定日期范围内的行

需要将整个 postgreSQL 数据库加载到 RAM 中

大型查询后 psycopg2 泄漏内存

每个数据库提供程序类型允许的最大参数数是多少?

PostgreSQL/JDBC 和 TIMESTAMP 与 TIMESTAMPTZ

带有偏移限制的 Select 查询太慢了

使用 SQLAlchemy 进行 PostgreSQL ILIKE 查询

升级到 Yosemite 10.10 后无法连接到 postgresql 数据库

在 Flask-sqlalchemy 和 Postgresql 中使用 JSON 类型