参数的 Postgres 类型不匹配

Postgres Type of Parameter does not match

我在使用 Postgres (10.5) 时遇到了一个奇怪的问题。我有一个函数 generate_unique_name,它接受三个文本值。它工作正常;但是,调用此函数似乎是一个问题。当我调用函数时使用:

 SELECT generate_unique_name('basic', 'seeds', 'project=' || 2)

它可以正常工作。我可以多次拨打同一个电话。现在,当我尝试相同的调用,但将第二个参数更改如下:

SELECT generate_unique_name('basic', 'queue', 'project=' || 2)

然后它似乎失败并出现错误:

ERROR: type of parameter 9 (text) does not match that when preparing the plan (character varying) CONTEXT: PL/pgSQL function generate_unique_name(text,text,text) line 12 at assignment SQL state: 42804

我尝试将查询更改为:

SELECT generate_unique_name('basic'::text, 'queue'::text, ('project=' || 2)::text)

但这也失败了。如果我然后终止与 postgres DB 的连接,并创建一个新连接,而不是从第二个查询开始,它现在可以工作,但第一个停止运行。

似乎 postgres 决定停止将参数作为文本处理,原因不明。我错过了什么吗?

编辑:generate_unique_name

的代码
CREATE OR REPLACE FUNCTION public.generate_unique_name(
    proposed_name text,
    table_name text,
    condition text)
    RETURNS text
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
AS $BODY$

DECLARE
    unique_name text;
    name_counter integer;
    r record;
    names_to_check text[];
BEGIN
    unique_name = proposed_name;
    name_counter = 0;

    FOR r IN EXECUTE 'SELECT name FROM ' || table_name || ' WHERE ' || condition LOOP
        names_to_check = array_append(names_to_check, r.name::text);
    END LOOP;

    WHILE unique_name = ANY(names_to_check) LOOP
        name_counter = name_counter + 1;
        unique_name = proposed_name || ' (' || name_counter || ')';
    END LOOP;
    RETURN unique_name;
END;

$BODY$;

我的猜测是 queue table 的 name 列中有一个值导致

出现问题
names_to_check = array_append(names_to_check, r.name::text) 

正如 Joe 所提到的,问题出在 array_append,我想不出解决办法。相反,generate_unique_names 函数被更改为只连续查询数据库。

CREATE OR REPLACE FUNCTION generate_unique_name (proposed_name text, table_name text, condition text) RETURNS text AS
$BODY$
DECLARE
    unique_name text;
    name_counter integer;
    not_unique boolean;
BEGIN
    unique_name = proposed_name;
    name_counter = 0;

    EXECUTE 'SELECT COUNT(*)!=0 FROM ' || table_name || ' WHERE ' || condition || ' AND name = ''' || unique_name || '''' INTO not_unique;

    WHILE not_unique LOOP
        name_counter = name_counter + 1;
        unique_name = proposed_name || ' (' || name_counter || ')';
        EXECUTE 'SELECT COUNT(*)!=0 FROM ' || table_name || ' WHERE ' || condition || ' AND name = ''' || unique_name || '''' INTO not_unique;
    END LOOP;
    RETURN unique_name;
END;
$BODY$ LANGUAGE plpgsql;