Postgres参数类型不匹配

时间:2018-11-30 19:15:54

标签: sql postgresql postgresql-10

我对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$;

2 个答案:

答案 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;