在PostgreSQL中找不到函数

P_A*_*_Ar 4 postgresql types casting user-defined-functions postgresql-11

我在PostgreSQL 11.2中创建了一个用户定义的函数,如下所示。它基本上将值插入到两个不同的表中:

CREATE OR REPLACE FUNCTION public.insertTest(
IN ID1 integer, 
IN Value1 character varying,
IN Value2 character varying,
IN Value3 character varying,
IN Status character varying,
IN Active_Flag integer, 
IN Stuff1 smallint,
IN stuff2 smallint)
RETURNS void
LANGUAGE 'plpgsql'

AS $BODY$
BEGIN

Insert into TableA 
(TA_ID,
 TA_Value1, 
 TA_Value2,
 TA_Value3, 
 TA_Value4,
 TA_Time, 
 TA_Flag)
values 
(ID1,
 Value1, 
 Value2,
 Value3, 
 Status,
 now(), 
 1);

Insert into TableB
(TA_ID,
 TB_ID,      Confidence,     Sev_Rate, 
 Last_Update_Time,   TB_Flag)
values
(currval('tablea_t_id_seq'), --TableA has an auto-increment field
 Active_Flag,    Stuff1,     Stuff2,
 now(), 
 0);

END;
$BODY$;
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试执行此功能时,以下操作无效:

SELECT * FROM public.insertTest (
550, 'Test_Value1', 
'Test_Value2', 'Test_Value3', 
'DEL', 55, 1, 1)
Run Code Online (Sandbox Code Playgroud)

并抛出此错误:

ERROR:  function insertTest(integer, unknown, unknown, unknown, unknown, integer, integer, integer) does not exist
LINE 1: select insertTest(550,'Test_Value1', 'Test_...
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
Run Code Online (Sandbox Code Playgroud)

但是以下工作原理:

SELECT * FROM public.insertTest (
550::integer, 'Test_Value1'::character varying, 
'Test_Value2'::character varying, 'Test_Value3'::character varying, 
'DEL'::character varying, 55::integer, 1::smallint, 1::smallint);
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我为什么第一次执行该功能无效吗?

Erw*_*ter 5

有人可以告诉我为什么第一次执行该功能无效吗?

确切的答案是:函数类型解析

varchar不是问题(不像另一个答案建议)。字符串文字(带有单引号)最初是类型,unknown并且对此进行隐式转换varchar

int2末尾的列是“问题”(或者更确切地说,是那些不匹配的输入)。该数字文字 1(不包括引号!)最初被认为是类型integer。并且没有integerint4)到smallintint2)的隐式转换。看到:

SELECT castsource::regtype, casttarget::regtype, castcontext
FROM   pg_cast
WHERE  castsource = 'int'::regtype
AND    casttarget = 'int2'::regtype;
Run Code Online (Sandbox Code Playgroud)

关于本手册castcontext

e表示仅作为显式强制转换(使用CAST::语法)。a意味着在隐式分配给目标列以及显式分配。i隐含在表达式中,以及其他情况

通过显式强制转换,函数调用成功:

SELECT * FROM pg_temp.insertTest (
550, 'Test_Value1', 
'Test_Value2', 'Test_Value3', 
'DEL', 55, int2 '1', int2 '1');
Run Code Online (Sandbox Code Playgroud)

甚至只是:

SELECT * FROM pg_temp.insertTest (
550, 'Test_Value1', 
'Test_Value2', 'Test_Value3', 
'DEL', 55,  '1', '1');
Run Code Online (Sandbox Code Playgroud)

现在,带有引号的是字符串文字,最初是type unknown,并且对它们进行隐式转换int2

db <> 在这里拨弄

密切相关,并提供分步说明:

  • 非常感谢您提供@Erwin的精彩信息。得到了答案 (2认同)