2016-01-09 14 views
0

所以我有這個任務,我必須做一個更新表的過程,當某個條件不符合時,它會顯示一條錯誤消息。我面對的唯一問題是在某行被鎖定並且無法更新時設置錯誤消息。我知道我必須使用PRAGMA並顯示一些錯誤消息資源鎖定/繁忙54但我不知道如何在代碼中使用它。這是我迄今爲止所做的:行鎖定時顯示錯誤消息PL/SQL

CREATE OR REPLACE PROCEDURE upd_jobsal(
par_job_id jobs.job_id%TYPE, 
par_min_sal jobs.min_salary%TYPE, 
par_max_sal jobs.max_salary%TYPE) IS 
v_job_id jobs.job_id%TYPE; 
invalid_sal EXCEPTION;       
BEGIN 
IF par_min_sal > par_max_sal THEN 
    RAISE invalid_sal; 
END IF; 
SELECT jobs.job_id 
INTO v_job_id 
FROM jobs 
WHERE jobs.job_id = par_job_id;            
UPDATE jobs SET 
    jobs.min_salary = par_min_sal, 
    jobs.max_salary = par_max_sal 
    WHERE jobs.job_id = v_job_id; 
EXCEPTION 
    WHEN invalid_sal THEN 
      DBMS_OUTPUT.PUT_LINE('The maximum salary is less than the minimum salary.'); 
    WHEN NO_DATA_FOUND THEN    
      DBMS_OUTPUT.PUT_LINE('That job id does not exist.'); 
END; 

任何幫助將不勝感激。預先感謝您的時間。

+1

爲什麼'SELECT ... INTO v_job_id ......'時,你可以做'更新作業SET ... WHERE JOB_ID = par_job_id'? – MT0

+0

是的,我知道它需要一些改進,我會更多地處理代碼,但目前我最需要幫助的是PRAGMA。 – Cr1ms0nStraY

回答

0

甲骨文設置

CREATE TABLE jobs (
    job_id NUMBER(5,0) CONSTRAINT jobs__ji__pk PRIMARY KEY, 
    min_salary NUMBER(9,2), 
    max_salary NUMBER(9,2) 
); 

INSERT INTO jobs VALUES (1, 100, 200); 

COMMIT; 

CREATE OR REPLACE PROCEDURE upd_jobsal(
    par_job_id jobs.job_id%TYPE, 
    par_min_sal jobs.min_salary%TYPE, 
    par_max_sal jobs.max_salary%TYPE 
) 
IS 
    v_job_id jobs.job_id%TYPE; 
    invalid_sal EXCEPTION; 
    row_locked EXCEPTION; PRAGMA EXCEPTION_INIT (row_locked, -54); 
BEGIN 
    IF par_min_sal > par_max_sal THEN 
     RAISE invalid_sal; 
    END IF; 

    SELECT job_id 
    INTO v_job_id 
    FROM jobs 
    WHERE job_id = par_job_id 
    FOR UPDATE OF min_salary, max_salary NOWAIT; 

    UPDATE jobs 
    SET min_salary = par_min_sal, 
     max_salary = par_max_sal 
    WHERE job_id  = par_job_id; 

EXCEPTION 
    WHEN invalid_sal THEN 
    DBMS_OUTPUT.PUT_LINE('The maximum salary is less than the minimum salary.'); 
    WHEN NO_DATA_FOUND THEN    
    DBMS_OUTPUT.PUT_LINE('That job id does not exist.'); 
    WHEN row_locked THEN 
    DBMS_OUTPUT.PUT_LINE('Row locked.'); 
END; 
/
SHOW ERRORS; 
/

測試

在會話1:

DECLARE 
    p_job_id JOBS.JOB_ID%TYPE; 
BEGIN 
    SELECT job_id 
    INTO p_job_id 
    FROM jobs 
    WHERE job_id = 1 
    FOR UPDATE OF min_salary, max_salary; 

    DBMS_LOCK.SLEEP(10); 

    UPDATE jobs 
    SET min_salary = min_salary + 10, 
     max_salary = max_salary + 10 
    WHERE job_id  = p_job_id; 
END; 
/

在會話2:

SET SERVEROUTPUT ON; 

BEGIN 
    upd_jobsal(
    par_job_id => 1, 
    par_min_sal => 900, 
    par_max_sal => 1000 
); 
END; 
/

會議2應輸出:

Row locked. 
+0

非常感謝。你寫的代碼幫了我很多。現在我終於可以回到優化代碼的整體。再次感謝您的時間。 – Cr1ms0nStraY