You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL报错:public.tt_add_log(numeric, numeric)存储过程不存在

问题解决:PostgreSQL存储过程调用参数类型不匹配错误

问题场景

编写了两个PostgreSQL存储过程:tt_merge用于合并两个表数据到第三个表,tt_add_log用于记录日志。调用tt_merge时触发错误:

SQL Error [42883]: ERROR: procedure public.tt_add_log(numeric, numeric) does not exist

尝试添加类型转换但未解决问题,相关存储过程代码如下:

tt_merge 代码

create or replace procedure tt_merge (p_id numeric)
language plpgsql
as
$$
declare 
v_row public.tt_eod%rowtype;
v_data public.tt_data%rowtype;
 v_cur cursor for  select dt.id
      ,dt.status 
      ,dt.col1 
      ,te.status 
      ,te.col1
  from tt_data dt
      ,tt_eod te 
 where dt.id =te.id 
   and te.id = p_id;
--   
begin
--
    open v_cur;
fetch v_cur into v_row;
--
    insert into tt_final (id,numbero ,col1)
    values(v_row.id, v_row.status,v_row.col1);
--
update tt_eod
set status =1
where id =v_row.id;
call public.tt_add_log (v_row.id::numeric,v_row.status+1::numeric);
    close v_cur;
--
commit;
--
end;
$$

tt_add_log 代码

CREATE OR REPLACE PROCEDURE public.tt_add_log(IN p_loglevel character varying, IN p_loginfo character varying)
 LANGUAGE plpgsql
AS $procedure$
declare
begin 
    insert into public.tt_log (loglevel,loginfo)
    values(p_loglevel, p_loginfo);
end;
$procedure$
;

错误原因

核心问题是参数类型不匹配:

  • tt_add_log定义的两个参数都是character varying(字符串类型)
  • 调用时传入的v_row.id::numeric和v_row.status+1::numeric都是numeric类型,即使做了类型转换,也是转换成了numeric而非字符串,PostgreSQL找不到对应参数类型的存储过程,因此报错。

另外,v_row.status+1::numeric的语法存在问题:::numeric只作用于1,正确的写法应该是(v_row.status + 1)::numeric,不过这不是本次报错的直接原因,但需要修正。

解决方案

将调用tt_add_log时的参数转换为character varying类型,确保与存储过程定义的参数类型一致。

修改后的tt_merge关键代码

将原调用行:

call public.tt_add_log (v_row.id::numeric,v_row.status+1::numeric);

替换为:

call public.tt_add_log (v_row.id::character varying, (v_row.status + 1)::character varying);

完整修改后的tt_merge代码

create or replace procedure tt_merge (p_id numeric)
language plpgsql
as
$$
declare 
v_row public.tt_eod%rowtype;
v_data public.tt_data%rowtype;
 v_cur cursor for  select dt.id
      ,dt.status 
      ,dt.col1 
      ,te.status 
      ,te.col1
  from tt_data dt
      ,tt_eod te 
 where dt.id =te.id 
   and te.id = p_id;
--   
begin
--
    open v_cur;
fetch v_cur into v_row;
--
    insert into tt_final (id,numbero ,col1)
    values(v_row.id, v_row.status,v_row.col1);
--
update tt_eod
set status =1
where id =v_row.id;
-- 修正参数类型转换,将numeric转为character varying
call public.tt_add_log (v_row.id::character varying, (v_row.status + 1)::character varying);
    close v_cur;
--
commit;
--
end;
$$

额外提示

  • 原游标仅fetch一次,只会处理符合条件的第一行数据,如果需要处理所有匹配行,应该使用loop循环配合fetch,直到游标无数据。
  • 建议使用显式的JOIN语法替代旧的逗号分隔表写法,提升代码可读性:
    v_cur cursor for  
      select dt.id, dt.status, dt.col1, te.status, te.col1
      from tt_data dt
      join tt_eod te on dt.id = te.id 
      where te.id = p_id;
    

内容的提问来源于stack exchange,提问作者Tvitmsvleli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:12:57