在 PostgreSQL 中找不到函数
Function not found in PostgreSQL
我在 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);
谁能告诉我为什么第一次执行函数不起作用?
正如您从错误消息中看到的那样,PostgreSQL 希望您调用 function insertTest(integer, unknown, unknown, unknown, unknown, integer, integer, integer)
。 character varying 类型的所有参数都不会被视为此类参数,因此输入将被转换为 unknown
.
您会在 this Whosebug post 中找到充分的解释(查看评论)。幸运的是,通过显式提供类型声明,您已经有了一个潜在的解决方案,至少对于您的 character varying 参数。
Can someone tell me why the 1st execution of the function does not work?
确切答案是:Function Type Resolution.
varchar
列 不是 问题(与另一个答案所暗示的不同)。 字符串文字(带单引号)最初是类型 unknown
并且有一个到 varchar
的隐式转换。
末尾的 int2
列是 "problem"(或者更确切地说,是那些不匹配的输入)。 数字文字 1
(不带引号!)最初假定为类型 integer
。并且 没有从 integer
(int4
) 到 smallint
(int2
) 的隐式转换 。参见:
SELECT castsource::regtype, casttarget::regtype, castcontext
FROM pg_cast
WHERE castsource = 'int'::regtype
AND casttarget = 'int2'::regtype;
e
means only as an explicit cast (using CAST
or ::
syntax). a
means implicitly in assignment to a target column, as well as explicitly. i
means implicitly in expressions, as well as the other cases
通过显式转换,函数调用成功:
SELECT * FROM pg_temp.insertTest (
550, 'Test_Value1',
'Test_Value2', 'Test_Value3',
'DEL', 55, <b>int2 '1', int2 '1'</b>);
甚至只是:
SELECT * FROM pg_temp.insertTest (
550, 'Test_Value1',
'Test_Value2', 'Test_Value3',
'DEL', 55, <b> '1', '1'</b>);
现在,添加引号后,它们是 字符串文字 ,最初键入 unknown
,然后隐式转换为 int2
。
db<>fiddle here
密切相关,有逐步解释:
- No function matches the given name and argument types
我在 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);
谁能告诉我为什么第一次执行函数不起作用?
正如您从错误消息中看到的那样,PostgreSQL 希望您调用 function insertTest(integer, unknown, unknown, unknown, unknown, integer, integer, integer)
。 character varying 类型的所有参数都不会被视为此类参数,因此输入将被转换为 unknown
.
您会在 this Whosebug post 中找到充分的解释(查看评论)。幸运的是,通过显式提供类型声明,您已经有了一个潜在的解决方案,至少对于您的 character varying 参数。
Can someone tell me why the 1st execution of the function does not work?
确切答案是:Function Type Resolution.
varchar
列 不是 问题(与另一个答案所暗示的不同)。 字符串文字(带单引号)最初是类型 unknown
并且有一个到 varchar
的隐式转换。
末尾的 int2
列是 "problem"(或者更确切地说,是那些不匹配的输入)。 数字文字 1
(不带引号!)最初假定为类型 integer
。并且 没有从 integer
(int4
) 到 smallint
(int2
) 的隐式转换 。参见:
SELECT castsource::regtype, casttarget::regtype, castcontext
FROM pg_cast
WHERE castsource = 'int'::regtype
AND casttarget = 'int2'::regtype;
e
means only as an explicit cast (usingCAST
or::
syntax).a
means implicitly in assignment to a target column, as well as explicitly.i
means implicitly in expressions, as well as the other cases
通过显式转换,函数调用成功:
SELECT * FROM pg_temp.insertTest (
550, 'Test_Value1',
'Test_Value2', 'Test_Value3',
'DEL', 55, <b>int2 '1', int2 '1'</b>);
甚至只是:
SELECT * FROM pg_temp.insertTest (
550, 'Test_Value1',
'Test_Value2', 'Test_Value3',
'DEL', 55, <b> '1', '1'</b>);
现在,添加引号后,它们是 字符串文字 ,最初键入 unknown
,然后隐式转换为 int2
。
db<>fiddle here
密切相关,有逐步解释:
- No function matches the given name and argument types