在PostgreSQL中找不到函数

aor9mmx1  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(2)|浏览(242)

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

字符串
现在,当我尝试执行此函数时,以下内容不起作用:

SELECT * FROM public.insertTest (
550, 'Test_Value1', 
'Test_Value2', 'Test_Value3', 
'DEL', 55, 1, 1)


并抛出此错误:

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.


但以下工作:

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);


有人能告诉我为什么第一次执行函数不工作吗?

xxslljrj

xxslljrj1#

.为什么第一次执行函数不起作用?
正确答案是:Function Type Resolution
varchar列不是问题所在(不像另一个答案所暗示的那样)。字符串字面量'Test_Value1'(带单引号)最初是unknown类型,并且有一个隐式转换为varchar
最后的int2列是“问题”(或者更确切地说,是这些列的不匹配输入)。数值字面量1(不带引号!)最初被假设为integer类型。并且从integerint4)到smallintint2)没有隐式转换。请参阅:

SELECT castsource::regtype, casttarget::regtype, castcontext
FROM   pg_cast
WHERE  castsource = 'int'::regtype
AND    casttarget = 'int2'::regtype;

字符串
显示castcontext = 'a'. The manual about castcontext :
e表示仅作为显式强制转换(使用CAST::语法)。a表示在对目标列的赋值中隐式,以及显式。i表示在表达式中隐式,以及其他情况
使用显式强制转换,函数调用成功:

SELECT * FROM pg_temp.insertTest (
550, 'Test_Value1', 
'Test_Value2', 'Test_Value3', 
'DEL', 55, int2 '1', int2 '1');


或者只是:

SELECT * FROM pg_temp.insertTest (
550, 'Test_Value1', 
'Test_Value2', 'Test_Value3', 
'DEL', 55,  '1', '1');


现在,加上引号,这些是 * 字符串字面量 *,最初类型为unknown,并且有一个隐式转换为int2
fiddle
密切相关,逐步解释:

  • 没有函数与给定的名称和参数类型匹配
  • 有没有办法在Postgres中禁用函数重载
goqiplq2

goqiplq22#

正如你从错误消息中看到的,PostgreSQL期望你调用function insertTest(integer, unknown, unknown, unknown, unknown, integer, integer, integer)。所有类型为 * charactervarying * 的参数都不被认为是这样的,因此输入将被转换为unknown
你会在this Stackoverflow post中找到一个足够的解释(看看注解)。幸运的是,你已经有了一个潜在的解决方案,通过显式地提供类型声明,至少对于你的 * 字符可变 * 参数。

相关问题