我对Postgres(10.5)有一个奇怪的问题。我有一个函数generate_unique_name
,它接受三个文本值。它工作正常;但是,调用此函数似乎是一个问题。当我使用以下命令调用函数时:
SELECT generate_unique_name('basic', 'seeds', 'project=' || 2)
它没有问题。我可以多次拨打相同的电话。现在,当我尝试相同的呼叫时,但如下更改第二个参数:
SELECT generate_unique_name('basic', 'queue', 'project=' || 2)
然后它似乎因错误而失败:
错误:参数9(文本)的类型与准备时的类型不匹配 计划(字符不同)上下文:PL / pgSQL函数 在分配SQL状态下的generate_unique_name(text,text,text)第12行: 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$;
答案 0 :(得分:1)
我的猜测是name
表的queue
列中有一个值导致
names_to_check = array_append(names_to_check, r.name::text)
答案 1 :(得分:0)
正如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;