当行被锁定PL / SQL时显示错误消息

时间:2016-01-09 17:44:22

标签: sql oracle plsql oracle-sqldeveloper pragma

所以我有这个任务,我必须创建一个更新表的过程,当不满足某个条件时,它会显示一条错误消息。我面临的唯一问题是当某行被锁定且无法更新时设置错误消息。我知道我必须使用 PRAGMA 并显示一些错误消息资源锁定/忙54 但我不知道如何在代码中使用它。这是我到目前为止所做的:

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 个答案:

答案 0 :(得分:0)

Oracle安装程序

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.