【问题标题】:Procedure Error: ORA-24344: success with compilation error过程错误:ORA-24344:编译错误成功
【发布时间】:2021-05-23 18:02:49
【问题描述】:

该过程需要两个日期并查找在此期间发布的报告,并更新总工资并打印它们。

CREATE OR REPLACE PROCEDURE Salary_Update(p_Date1 DATE, p_Date2 DATE) AS 
CURSOR MYCR IS 
SELECT ReportID, TotalSale, Rate, TotalSalary, ReportDate
FROM WEEKLY_REPORT
WHERE ReportDate BETWEEN TO_DATE(p_Date1, 'DD-MM-YYYY') AND TO_DATE(p_Date2, 'DD-MM-YYYY'); 
BEGIN
FOR MYPOINTER IN MYCR LOOP
UPDATE WEEKLY_REPORT SET TotalSalary = ((TotalSale/100)*Rate);
DBMS_OUTPUT.PUT_LINE('The total salary for report ' || MYPOINTER.REPORTID || '  updated to ' || MYPOINTER.TotalSalary || 'dollars, which is ' || MYPOINTER.Rate || '% of the total sale of ' || MYPOINTER.TotalSale || 'dollars.');
WHERE ReportID = MYPOINTER.ReportID;
END LOOP;
END Salary_Update;
/

执行

BEGIN Salary_Update('02-04-2020','05-04-2020');
END;
BEGIN 
Salary_Update(to_date('02-04-2020','dd-mm-yyyy'), to_date('05-04-2020','dd-mm-yyyy'));
END;

两者都不起作用。

【问题讨论】:

  • 编译后做show errors,或者查询user_errors,看看有什么问题。首先,您的更新包含 := 而不是 =
  • @AlexPoole 我使用 oracle apex。显示错误不起作用
  • 您可以按照@AlexPoole 的建议查询user_errors。您正在对date 进行to_date 调用,除了update 中的错误之外,这没有任何意义。您的update 语句会更新表的每一行,因为没有where 子句。打开一个遍历表中每一行的游标然后在循环中过滤掉大部分行的if 语句确实没有意义。那应该是游标定义中的where 子句。
  • 您的输入参数被定义为 DATE,但是当您调用该过程时,您正在提供字符串。 DATE 是一种内部的二进制数据类型。
  • DBMS_OUTPUT 适用于调试,但不适用于正式报告。它写入屏幕。它写入内部缓冲区。然后,当操作控制权返回给调用者时,该缓冲区过程完成后传递回调用程序。然后由调用者决定是否处理缓冲区。并且一些调用程序甚至可能没有被编程为能够处理它。

标签: oracle plsql


【解决方案1】:

存在许多语法和逻辑错误。您还没有具体说明您希望代码做什么或提供可重现的测试用例,但我猜您想要类似的东西

CREATE OR REPLACE PROCEDURE Salary_Update(
  p_Date1 DATE, 
  p_Date2 DATE) 
AS 
  CURSOR MYCR IS 
    SELECT ReportID, TotalSale, Rate, TotalSalary, ReportDate
      FROM WEEKLY_REPORT
     WHERE ReportDate BETWEEN p_date1 AND p_date2;
BEGIN
  FOR MYPOINTER IN MYCR 
  LOOP
    UPDATE WEEKLY_REPORT 
       SET TotalSalary = ((TotalSale/100)*Rate)
     WHERE ReportID = MYPOINTER.ReportID;
    DBMS_OUTPUT.PUT_LINE('The total salary for report ' || MYPOINTER.REPORTID || '  updated to ' || MYPOINTER.TotalSalary || 'dollars, which is ' || MYPOINTER.Rate || '% of the total sale of ' || MYPOINTER.TotalSale || 'dollars.');
  END LOOP;
END Salary_Update;
/

您输出的字符串似乎没有意义——MYPOINTER.TotalSalary 是游标中的值,它将是更新前的值。如果打印出更新 TotalSalary 的值很重要,您可能需要类似

CREATE OR REPLACE PROCEDURE Salary_Update(
  p_Date1 DATE, 
  p_Date2 DATE) 
AS 
  CURSOR MYCR IS 
    SELECT ReportID, TotalSale, Rate, TotalSalary, ReportDate
      FROM WEEKLY_REPORT
     WHERE ReportDate BETWEEN p_date1 AND p_date2;
  l_newSalary weekly_report.totalSalary%type;
BEGIN
  FOR MYPOINTER IN MYCR 
  LOOP
    l_newSalary := (mypointer.TotalSale/100) * mypointer.rate;
    UPDATE WEEKLY_REPORT 
       SET TotalSalary = l_newSalary
     WHERE ReportID = MYPOINTER.ReportID;
    DBMS_OUTPUT.PUT_LINE('The total salary for report ' || MYPOINTER.REPORTID || '  updated to ' || l_newSalary || 'dollars, which is ' || MYPOINTER.Rate || '% of the total sale of ' || MYPOINTER.TotalSale || 'dollars.');
  END LOOP;
END Salary_Update;
/

如果您收到的错误是 weekly_report 不存在的 ORA-00942 错误,则当前架构中没有这样的表。假设查询在交互式运行时有效,可能该表存在于不同的模式中,该表的当前模式中有一个本地同义词,并且过程的所有者只能访问通过角色授予的表。在这种情况下,您需要您的 DBA 将对表的访问权限直接授予过程所有者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多