【问题标题】:Function not found in PostgreSQL在 PostgreSQL 中找不到函数
【发布时间】:2019-12-20 13:58:51
【问题描述】:

我在 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 types casting user-defined-functions postgresql-11


    【解决方案1】:

    从错误消息中可以看出,PostgreSQL 期望您调用function insertTest(integer, unknown, unknown, unknown, unknown, integer, integer, integer)字符变化类型的所有参数都不会被视为这样,因此输入将被转换为unknown

    您会在this Stackoverflow post 中找到充分的解释(查看 cmets)。幸运的是,您已经有了一个潜在的解决方案,即显式提供类型声明,至少对于 character varying 参数是这样。

    【讨论】:

      【解决方案2】:

      谁能告诉我为什么第一次执行该函数不起作用?

      确切的答案是:Function Type Resolution

      varchar不是问题(与另一个答案所暗示的不同)。 字符串字面量(带单引​​号)最初是 unknown 类型,并且为此隐式转换为 varchar

      末尾的int2 列是“问题”(或者更确切地说,是那些不匹配的输入)。 数字文字 1(不带引号!)最初假定为integer 类型。从integer (int4) 到smallint (int2) 之间没有隐式转换。见:

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

      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

      db小提琴here

      密切相关,分步说明:

      【讨论】:

        猜你喜欢
        • 2016-02-27
        • 2019-05-02
        • 2023-01-18
        • 1970-01-01
        • 2017-05-24
        • 2019-03-07
        • 2021-06-17
        • 2015-10-29
        • 1970-01-01
        相关资源
        最近更新 更多