参数的 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;
我在使用 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;