2014-01-13 28 views
1

我在PL/SQL的新手,我有下面的代碼的問題:得到錯誤的PL/SQL的Oracle

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 compiled
Errors: check compiler log

如果有人可以幫助我,我會感激

+0

又是什麼**的編譯器日誌**說什麼? – peterm

+0

你得到的錯誤只是一個編譯器消息,說有錯誤。你必須做一個'SELECT * FROM user_errors WHERE name ='CHECK_AVGSAL''來查看實際的錯誤。請在這裏發佈這些。 – Rachcha

+0

錯誤(36,1):PLS-00103:遇到符號「EXECUTE」 – pecabum

回答

3

你需要對自己的一條線/,該end chk_avgsal;和下一條語句,to run the PL/SQL block之間:

... 
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

+0

並獲得錯誤(2,17):PL/SQL:忽略項目 錯誤(2,27):PLS-00302:必須聲明組件'EXCEED_AVGSAL' 錯誤(21,1):PLS-00320:聲明該表達式的類型不完整或格式不正確 錯誤(21,1):PL/SQL:語句被忽略 錯誤(23,1):PLS-00320:此表達式的類型聲明不完整或格式錯誤 :PL/SQL:忽略語句 :PL/SQL:忽略SQL語句 :PLS-00320:此表達式類型的聲明不完整或格式錯誤 PL/SQL:ORA-00904:「AVGSAL_EXCEEDED」:無效標識符 PLS- 00103:遇到符號「/」 – pecabum

+0

您的'alter table'失敗 - 當您執行s時會顯示CRIPT! - 因此編譯過程時新列不存在。如果這是一次性的,您可以將其作爲匿名塊來執行,而不是創建存儲過程;或者像Wenfried說的那樣,用一個simole更新語句 - 不需要PL/SQL。 –

1

你忘了分號:

EXECUTE check_avgsal; 

但是你可以做一個簡單的UPDATE:

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); 
+0

我已經修好了分號,但是有:SQL錯誤:ORA-00904: 「E」 「EXCEED_AVGSAL」:無效的標識符 00904. 00000 - 「%S:無效的標識符」 *原因: *動作: COMMITED – pecabum

+0

您沒有將列EXCEED_AVGSAL添加到employees表中。 –