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
相关产品推荐
相关产品推荐

