ORA-24344编译错误:Oracle Salary_Update存储过程执行失败求助
Oracle存储过程ORA-24344报错排查及修复
核心错误原因
- UPDATE语句语法顺序错误:UPDATE的
WHERE过滤子句被放到了DBMS_OUTPUT.PUT_LINE打印语句之后,Oracle语法要求UPDATE的SET配置后必须紧跟WHERE过滤条件,中间不能插入其他执行语句,这是触发编译报错的核心原因 - 日期参数重复转换:存储过程的入参
p_Date1、p_Date2已经声明为DATE类型,不需要再用TO_DATE做转换,重复转换会触发隐式类型转换,容易出现格式不匹配报错 - 打印值为旧数据:游标中查询的是更新前的
TotalSalary值,直接打印会显示更新前的数值,和实际更新后的数据不符 - 第一种执行方式入参类型不匹配:存储过程入参是DATE类型,直接传字符串会依赖会话的默认日期格式,大概率触发类型转换失败
修复后的存储过程代码
CREATE OR REPLACE PROCEDURE Salary_Update(p_Date1 DATE, p_Date2 DATE) AS CURSOR MYCR IS SELECT ReportID, TotalSale, Rate, ReportDate FROM WEEKLY_REPORT WHERE ReportDate BETWEEN p_Date1 AND p_Date2; -- 存储更新后的薪资值 v_new_salary NUMBER; BEGIN FOR MYPOINTER IN MYCR LOOP -- 提前计算新薪资 v_new_salary := (MYPOINTER.TotalSale/100)*MYPOINTER.Rate; -- 修正UPDATE语句顺序,WHERE紧跟SET UPDATE WEEKLY_REPORT SET TotalSalary = v_new_salary WHERE ReportID = MYPOINTER.ReportID; -- 打印更新后的正确值 DBMS_OUTPUT.PUT_LINE('The total salary for report ' || MYPOINTER.REPORTID || ' updated to ' || v_new_salary || ' dollars, which is ' || MYPOINTER.Rate || '% of the total sale of ' || MYPOINTER.TotalSale || ' dollars.'); END LOOP; -- 提交事务,可根据需求调整是否在存储过程内提交 COMMIT; END Salary_Update; /
正确执行方式
-- 执行前先开启输出,才能看到打印信息 SET SERVEROUTPUT ON; -- 推荐用显式日期转换的方式执行,不受会话日期格式影响 BEGIN Salary_Update(to_date('02-04-2020','dd-mm-yyyy'), to_date('05-04-2020','dd-mm-yyyy')); END; /
额外注意事项
- 如果需要兼容字符串格式的日期入参,可以把存储过程的入参类型改为VARCHAR2,再在内部做
TO_DATE转换即可 - 如果不需要在存储过程内部提交事务,可以删除
COMMIT语句,执行完成后手动提交即可
内容的提问来源于stack exchange,提问作者JK1
相关产品推荐
相关产品推荐

