在PL / SQL Oracle中获取错误

时间:2014-01-13 08:15:38

标签: sql oracle plsql syntax-error

我是PL / SQL的新手,我遇到以下代码问题:

ALTER TRIGGER secure_employees DISABLE;

ALTER TABLE employees ( ADD (exceed_avgsal VARCHAR2(3) DEFAULT 'NO' 
 CONSTRAINT employees_exceed_avgsal_ck CHECK (exceed_avgsal IN ('YES', 'NO')));

CREATE OR REPLACE PROCEDURE check_avgsal IS
  avgsal_exceeded employees.exceed_avgsal%type;
  CURSOR emp_csr IS
    SELECT employee_id, job_id, salary FROM employees FOR UPDATE;
  e_resource_busy EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_resource_busy, -54);

  FUNCTION get_job_avgsal(jobid VARCHAR2) RETURN NUMBER IS
    avg_sal employees.salary%type;
  BEGIN
    SELECT (max_salary + min_salary) / 2
      INTO avg_sal
      FROM jobs
     WHERE job_id = jobid;
    RETURN avg_sal;
  END;
BEGIN
  FOR emprec IN emp_csr LOOP
    avgsal_exceeded := 'NO';
    IF emprec.salary >= get_job_avgsal(emprec.job_id) THEN
      avgsal_exceeded := 'YES';
    END IF;
    UPDATE employees
       SET exceed_avgsal = avgsal_exceeded
     WHERE CURRENT OF emp_csr;
  END LOOP;
EXCEPTION
  WHEN e_resource_busy THEN
    ROLLBACK;
    RAISE_APPLICATION_ERROR(-20001, 'Record is busy, try later.');
END check_avgsal;

EXECUTE check_avgsal 

SELECT e.employee_id, e.job_id, (j.max_salary-j.min_salary/2) job_avgsal, e.salary, e.exceed_avgsal avg_exceeded 
 FROM employees e, jobs j WHERE e.job_id = j.job_id and e.exceed_avgsal = 'YES';
COMMIT;

我收到错误消息

  

PROCEDURE CHECK_AVGSAL编译了   错误:检查编译器日志

如果有人能帮助我,我会感激不尽

2 个答案:

答案 0 :(得分:3)

您需要在/和下一个语句to run the PL/SQL block之间的一行end chk_avgsal;

...
END LOOP; 
EXCEPTION WHEN e_resource_busy THEN ROLLBACK; 
RAISE_APPLICATION_ERROR (-20001, 'Record is busy, try later.');
END check_avgsal;
/

EXECUTE check_avgsal 
...

您的alter table语法也是错误的:

ALTER TABLE employees ADD (exceed_avgsal VARCHAR2(3) DEFAULT 'NO',
  CONSTRAINT employees_exceed_avgsal_ck CHECK (exceed_avgsal IN ('YES', 'NO')));

SQL Fiddle demo

答案 1 :(得分:1)

你忘记了分号:

EXECUTE check_avgsal;

但你可以在一个简单的更新中完成:

UPDATE employees e
    SET avgsal_exceeded = (
WITH avg_salaries AS 
    (SELECT (max_salary + min_salary)/2 AS avg_sal, job_id FROM jobs)
SELECT CASE 
    WHEN employee_id >= avg_sal THEN 'YES'
    ELSE 'NO'
    END
FROM avg_salaries
    WHERE a.job_id = e.job_id);