1. 程式人生 > >《Oracle PL/SQL例項精講》學習筆記11——異常 (高階概念)

《Oracle PL/SQL例項精講》學習筆記11——異常 (高階概念)

本章介紹瞭如下內容:

1. RAISE_APPLICATION_ERROR

“在我們寫proc程式中經常要有錯誤處理,在錯誤處理中我們經常要輸出錯誤資訊來給幫助我們分析和解決錯誤原因,從而更正資料。這時候就會用到SQLCODE和SQLERRM. SQLCode:資料庫操作的返回碼,其中0表示成功;-1表示失敗;100表示沒有檢索到資料;+1表示使用者自定義異常。 sqlerrm函式 sqlerrm函式返回指定錯誤程式碼的錯誤資訊。 一個Oracle的錯誤訊息最多隻能包含512個位元組的錯誤程式碼。如果沒有異常被觸發,則SQLCODE返回0,SQLERRM返回“ORA-0000:normal, successful completion”。 sqlerrm如何使用? sqlcode和sqlerrm是不能直接在sql語句中使用,必須先將其賦給變數後,才能在sql語句中使用,如下: v_trans_error NUMBER; v_trans_error_msg VARCHAR2(512); v_trans_error := SQLCODE; v_trans_error_msg := SUBSTR(SQLERRM,1,512);”

程式碼如下:

-- *** Chapter Exercises *** --
-- For Example ch10_1a.sql (In chapter 9, this is example ch09_2a.sql)
DECLARE
   v_student_id    STUDENT.STUDENT_ID%TYPE := &sv_student_id;
   v_total_courses NUMBER;
   e_invalid_id    EXCEPTION;
BEGIN
   IF v_student_id < 0 
   THEN
      RAISE e_invalid_id;
   END IF;

   SELECT COUNT(*)
     INTO v_total_courses
     FROM enrollment
    WHERE student_id = v_student_id;
   
   DBMS_OUTPUT.PUT_LINE ('The student is registered for '||v_total_courses||' courses');
   DBMS_OUTPUT.PUT_LINE ('No exception has been raised');
EXCEPTION
   WHEN e_invalid_id 
   THEN
      DBMS_OUTPUT.PUT_LINE ('An id cannot be negative');
END; 

-- For Example ch10_1b.sql 
DECLARE
   v_student_id    STUDENT.STUDENT_ID%TYPE := &sv_student_id;
   v_total_courses NUMBER;
BEGIN
   IF v_student_id < 0 
   THEN
      RAISE_APPLICATION_ERROR (-20000, 'An id cannot be negative'); 
   END IF;

   SELECT COUNT(*)
     INTO v_total_courses
     FROM enrollment
    WHERE student_id = v_student_id;
   
   DBMS_OUTPUT.PUT_LINE ('The student is registered for '|| v_total_courses||' courses');
END;

-- For Example ch10_2a.sql 
DECLARE
   v_student_id STUDENT.STUDENT_ID%TYPE := &sv_student_id;
   v_name       VARCHAR2(50);
BEGIN
   SELECT first_name||' '||last_name
     INTO v_name
     FROM student
    WHERE student_id = v_student_id;
   DBMS_OUTPUT.PUT_LINE (v_name);
EXCEPTION
   WHEN NO_DATA_FOUND 
   THEN
      RAISE_APPLICATION_ERROR (-20001, 'This ID is invalid');
END;

-- For Example ch10_3a.sql 
DECLARE
   v_zip ZIPCODE.ZIP%TYPE := '&sv_zip';
BEGIN
   DELETE FROM zipcode
    WHERE zip = v_zip;
   
   DBMS_OUTPUT.PUT_LINE ('Zip '||v_zip||' has been deleted');
   COMMIT;
END;

-- For Example ch10_3b.sql 
DECLARE
   v_zip          ZIPCODE.ZIP%TYPE := '&sv_zip';
   e_child_exists EXCEPTION;
   PRAGMA EXCEPTION_INIT(e_child_exists, -2292);
BEGIN
   DELETE FROM zipcode
    WHERE zip = v_zip;
   
   DBMS_OUTPUT.PUT_LINE ('Zip '||v_zip||' has been deleted');
   COMMIT;
EXCEPTION
   WHEN e_child_exists 
   THEN
      DBMS_OUTPUT.PUT_LINE ('Delete students for this zipcode first');
END;

-- For Example ch10_4a.sql 
DECLARE
   v_zip   VARCHAR2(5) := '&sv_zip';
   v_city  VARCHAR2(15);
   v_state CHAR(2);
BEGIN
   SELECT city, state
     INTO v_city, v_state
     FROM zipcode
    WHERE zip = v_zip;
   
   DBMS_OUTPUT.PUT_LINE (v_city||', '||v_state);

EXCEPTION
   WHEN OTHERS 
   THEN 
      DBMS_OUTPUT.PUT_LINE ('An error has occurred');
END;

-- For Example ch10_4b.sql 
DECLARE
   v_zip      VARCHAR2(5) := '&sv_zip';
   v_city     VARCHAR2(15);
   v_state    CHAR(2);
   v_err_code NUMBER;
   v_err_msg  VARCHAR2(200);
BEGIN
   SELECT city, state
     INTO v_city, v_state
     FROM zipcode
    WHERE zip = v_zip;
   
   DBMS_OUTPUT.PUT_LINE (v_city||', '||v_state);

EXCEPTION
   WHEN OTHERS 
   THEN
      v_err_code := SQLCODE;
      v_err_msg  := SUBSTR(SQLERRM, 1, 200);
      DBMS_OUTPUT.PUT_LINE ('Error code: '||v_err_code);
      DBMS_OUTPUT.PUT_LINE ('Error message: '||v_err_msg);
END;

-- For Example ch10_5a.sql 
BEGIN
   DBMS_OUTPUT.PUT_LINE ('Error code: '||SQLCODE);
   DBMS_OUTPUT.PUT_LINE ('Error message1: '||SQLERRM(SQLCODE));
   DBMS_OUTPUT.PUT_LINE ('Error message2: '||SQLERRM(100));
   DBMS_OUTPUT.PUT_LINE ('Error message3: '||SQLERRM(200));
   DBMS_OUTPUT.PUT_LINE ('Error message4: '||SQLERRM(-20000));
END;

-- *** Web Chapter Exercises *** --
-- For Example ch10_6a.sql 
DECLARE
   v_students NUMBER(3) := 0;
BEGIN
   SELECT COUNT(*)
     INTO v_students
     FROM enrollment e, section s
    WHERE e.section_id = s.section_id
      AND s.course_no  = 25
      AND s.section_id = 89; 

   DBMS_OUTPUT.PUT_LINE ('Course 25, section 89 has '||v_students||' students');
END;

-- For Example ch10_6b.sql 
DECLARE
   v_students NUMBER(3) := 0;
BEGIN
   SELECT COUNT(*)
     INTO v_students
     FROM enrollment e, section s
    WHERE e.section_id = s.section_id
      AND s.course_no  = 25
      AND s.section_id = 89; 

   IF v_students > 10 
   THEN
      RAISE_APPLICATION_ERROR 
         (-20002, 'Course 25, section 89 has more than 10 students');
   END IF;

   DBMS_OUTPUT.PUT_LINE ('Course 25, section 89 has '||v_students||' students');
END;

-- For Example ch10_7a.sql 
BEGIN
   INSERT INTO course 
      (course_no, description, created_by, created_date)
   VALUES 
      (COURSE_NO_SEQ.NEXTVAL, 'Test Course', USER, SYSDATE);
   COMMIT;
   DBMS_OUTPUT.PUT_LINE ('One course has been added');
END;

-- For Example ch10_7b.sql 
DECLARE
   e_constraint_violation EXCEPTION;
   PRAGMA EXCEPTION_INIT(e_constraint_violation, -1400);
BEGIN
   INSERT INTO course 
      (course_no, description, created_by, created_date)
   VALUES 
      (COURSE_NO_SEQ.NEXTVAL, 'Test Course', USER, SYSDATE);
   COMMIT;
   DBMS_OUTPUT.PUT_LINE ('One course has been added');
EXCEPTION
   WHEN e_constraint_violation 
   THEN
      DBMS_OUTPUT.PUT_LINE ('INSERT statement is violating a constraint');
END;

-- For Example ch10_8a.sql 
BEGIN
   INSERT INTO zipcode 
      (zip, city, state, created_by, created_date, modified_by, modified_date)
   VALUES 
      ('10027', 'NEW YORK', 'NY', USER, SYSDATE, USER, SYSDATE);
   COMMIT;
END;

-- For Example ch10_8b.sql 
BEGIN
   INSERT INTO zipcode
      (zip, city, state, created_by, created_date, modified_by, modified_date)
   VALUES 
      ('10027', 'NEW YORK', 'NY', USER, SYSDATE, USER, SYSDATE);
   COMMIT;
EXCEPTION
   WHEN OTHERS 
   THEN
      DECLARE
         v_err_code NUMBER := SQLCODE;
         v_err_msg VARCHAR2(100) := SUBSTR(SQLERRM, 1, 100);
      BEGIN
         DBMS_OUTPUT.PUT_LINE ('Error code: '||v_err_code);
         DBMS_OUTPUT.PUT_LINE ('Error message: '||v_err_msg);
      END;
END;

-- For Example ch10_9a.sql
DECLARE
   v_section_id        NUMBER := &sv_section_id;
   v_total_students    NUMBER;
BEGIN
   -- Calculate number of students enrolled
   SELECT COUNT(*)
     INTO v_total_students
     FROM enrollment
    WHERE section_id = v_section_id;
         
   IF v_total_students >= 10 
   THEN
      RAISE_APPLICATION_ERROR 
         (-20000, 'There are too many students for section '||v_section_id);
   ELSE
      DBMS_OUTPUT.PUT_LINE 
         ('There are '||v_total_students||' students in section '||v_section_id);
   END IF;
END;

-- For Example ch10_10a.sql
BEGIN
   INSERT INTO instructor 
      (instructor_id, salutation, first_name, last_name, street_address, zip, phone)
   VALUES 
      (INSTRUCTOR_ID_SEQ.NEXTVAL, 'Mr', 'John', 'Smith', '123 Main St.', '00914'
      ,'1234567890');
   COMMIT; 
END;

-- For Example ch10_10b.sql
DECLARE
   e_non_null_value EXCEPTION;
   PRAGMA EXCEPTION_INIT(e_non_null_value, -1400);
BEGIN
   INSERT INTO instructor 
      (instructor_id, salutation, first_name, last_name, street_address, zip, phone)
   VALUES 
      (INSTRUCTOR_ID_SEQ.NEXTVAL, 'Mr', 'John', 'Smith', '123 Main St.', '00914'
      ,'1234567890');
   COMMIT; 
EXCEPTION
   WHEN e_non_null_value 
   THEN
      DBMS_OUTPUT.PUT_LINE 
         ('A NULL value cannot be inserted. '||
          ' Check constraints on the INSTRUCTOR table.');
END;

-- For Example ch10_10c.sql
BEGIN
   INSERT INTO instructor 
      (instructor_id, salutation, first_name, last_name, street_address, zip, phone)
   VALUES 
      (INSTRUCTOR_ID_SEQ.NEXTVAL, 'Mr', 'John', 'Smith', '123 Main St.', '00914'
      ,'1234567890');
   COMMIT; 
EXCEPTION
   WHEN OTHERS 
   THEN
      DBMS_OUTPUT.PUT_LINE ('Error code: '||SQLCODE);
      DBMS_OUTPUT.PUT_LINE ('Error message: '||SUBSTR(SQLERRM, 1, 200));
END;


select INSTRUCTOR_ID_SEQ.NEXTVAL from dual