Oracle學習第六天

回顧內容:

  1. 怎麼創建表空間?
  2. 怎麼創建用戶?怎麼給用戶權限?

 

本次學習內容講解:

  1. PL/SQL

1)、PL/SQL塊的結構。

2)、一般運算符、邏輯運算符。

3)、常量和變量的聲明。

4)、標識符命名規則。

5)、註釋。

  1. PL/SQL數據類型
  1. 標量數據類型。
  2. LOB數據類型。
  3. 屬性類型:%TYPE、%ROWTYPE。
  1. PL/SQL控制語句

1)、條件控制語句:IF、CASE。

2)、循環控制語句:LOOP、WHILE、FOR。

3)、順序控制語句:NULL。

  1. 異常

1)、預定義異常。

2)、自定義異常。

  1. 遊標

1)、靜態遊標(顯示和隱式)。

  1、循環遊標:LOOP、FOR。

  2、顯式遊標屬性:%FOUND、%NOTFOUND、%ROWCOUNT、%ISOPEN。

  3、使用顯示遊標刪除或更新。

  4、NO_DATA_FOUND和%NOTFOUND區別。

2)、動態遊標。

  1. 存儲過程

1)、子程序組成:聲明部分、可執行部分、異常處理部分。

2)、創建存儲過程、調用存儲過程(按位置、按名稱)。

3)、程序過程的參數模式:IN、OUT、IN OUT。

4)、存儲過程的訪問權限。

5)、刪除存儲過程。

6)、存儲過程調試。

7)、存儲過程規範。

一、for讀取遊標

-- Created on 2014/7/24 by ADMINISTRATOR 
declare 
  -- Local variables here
  CURSOR cursor_emp IS SELECT ename,sal FROM scott.emp ;
begin
  -- Test statements here
  
  --使用for循環
  FOR emp_row IN cursor_emp LOOP
      dbms_output.put_line(emp_row.ename || emp_row.sal || '    ' || cursor_emp%Rowcount);
  END LOOP;
  
end;

二、loop讀取遊標

declare 
  -- Local variables here
  i integer;
  v_ename scott.emp.ename%TYPE;
  v_sal scott.emp.sal%TYPE;
  CURSOR cursor_emp IS SELECT ename,sal FROM scott.emp;
begin
  -- Test statements here
  
  --打開遊標  如果沒有打開纔打開
  IF NOT cursor_emp%ISOPEN THEN
      OPEN cursor_emp;
  END IF;
  
  --使用loop讀取遊標
  LOOP
      --讀取下一行
      FETCH cursor_emp INTO v_ename,v_sal;
      
            dbms_output.put_line(v_ename || v_sal);
            
      --如果沒有行  則退出
      EXIT WHEN cursor_emp%NOTFOUND;
  END LOOP;
  
  --關閉遊標
  CLOSE cursor_emp;
  
end;

三、刪除表的存儲過程:
/**
*刪除數據庫表
 in_tablename  刪除表的名稱
 out_err_code  0刪除成功   -1沒有找到相關的表 -2 存儲過程執行異常
 out_err_msg 返回的執行信息
*/
create or replace procedure p_del_table(
       in_tablename IN VARCHAR2,
       out_err_code OUT VARCHAR2,
       out_err_msg OUT VARCHAR2 
)
AS
 v_count NUMBER;
begin
  SELECT COUNT(1) INTO v_count FROM dual WHERE EXISTS (
         SELECT * FROM User_Tables WHERE table_name=upper(in_tablename)
  );
  
  IF v_count > 0 THEN
     out_err_code := 0; 
     out_err_msg :=  '刪除成功';
     EXECUTE IMMEDIATE 'DROP TABLE ' || in_tablename;
  ELSE
     out_err_code := -1; 
     out_err_msg :=  '沒有找到表';
     DBMS_OUTPUT.put_line('沒有找到表');
  END IF;
  
EXCEPTION
   WHEN OTHERS THEN
       out_err_code := -2; 
       out_err_msg :=  '存儲過程執行異常';
  
end p_del_table;
/

 

l四、異常:


/*
===========================================================
|         預定義異常
============================================================
*/
DECLARE
   v_ename employee.ename%TYPE;
BEGIN
   SELECT ename INTO v_ename 
   FROM employee 
   WHERE empno=1234;
   dbms_output.put_line('僱員名:'||v_ename);
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      dbms_output.put_line('僱員號不正確');   
   WHEN TOO_MANY_ROWS THEN
      dbms_output.put_line('查詢只能返回單行');
   WHEN OTHERS THEN
      dbms_output.put_line('錯誤號:'||SQLCODE||'錯誤描述:'||SQLERRM);
END;


/*
===========================================================
|         預定義異常
============================================================
*/
DECLARE 
   v_empno scott.EMP.EMPNO%TYPE ;
   EMPNO_REPEAT EXCEPTION;   --1.定義異常變量
   PRAGMA EXCEPTION_INIT(EMPNO_REPEAT,-1407); --2.關聯異常代碼  ,1407不能爲NULL值
BEGIN
   
   UPDATE scott.EMP SET empno = NULL WHERE empno = 7369;
EXCEPTION
   WHEN EMPNO_REPEAT THEN  --3、捕捉異常定義的異常處理
     DBMS_OUTPUT.put_line('部門編號不能爲空');
END;

/*
===========================================================
|         用戶自定義異常
============================================================
*/
DECLARE
   v_empno scott.EMP.EMPNO%TYPE := 7000;
   NO_RESULT EXCEPTION;   --1.定義異常變量
BEGIN
   UPDATE scott.EMP SET sal = sal+100 WHERE empno = v_empno;
   
   --2.判斷是否有執行UPDATE
   IF SQL%NOTFOUND THEN
      RAISE NO_RESULT; --3.沒有執行UPDATE,拋出自定義異常
   END IF;
EXCEPTION
   WHEN NO_RESULT THEN --4.捕獲異常
      DBMS_OUTPUT.PUT_LINE('你的數據更新語句失敗了!');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;


/*
===========================================================
|         用戶自定義異常
============================================================
*/

CREATE OR REPLACE FUNCTION F_TEST(i_code IN NUMBER)
RETURN NUMBER IS RET_CODE NUMBER;
BEGIN
   
    IF i_code IS NULL THEN
       RAISE_APPLICATION_ERROR(-20991,'i_code不能爲空'); --1.寫入自定義代碼和錯誤信息
    ELSIF i_code > 1 THEN
       RAISE_APPLICATION_ERROR(-20992,'i_codeD太大了'); --1.寫入自定義代碼和錯誤信息
    ELSE
       RET_CODE := i_code;
       RETURN RET_CODE;
    END IF;
END F_TEST;

DECLARE
  v_result NUMBER;
  v_code NUMBER;
  CODE_NOT_NULL EXCEPTION;  --定義異常
  CODE_LIMITED EXCEPTION;   --定義異常
  PRAGMA EXCEPTION_INIT(CODE_NOT_NULL,-20991);  --2.初始化異常信息
  PRAGMA EXCEPTION_INIT(CODE_LIMITED,-20992);   --2.初始化異常信息
BEGIN
    --v_result := F_TEST(NULL);
    v_result := F_TEST(2); --3.調用函數 
EXCEPTION        --4.捕獲異常
   WHEN CODE_NOT_NULL THEN
     DBMS_OUTPUT.put_line('代碼不能爲空');
   WHEN CODE_LIMITED THEN
     DBMS_OUTPUT.put_line('數字太大了哦');
   WHEN OTHERS THEN
     DBMS_OUTPUT.put_line('其它異常');
END;

預定義異常:

錯誤號

異常錯誤信息名稱

說明

ORA-0001

Dup_val_on_index

違反了唯一性限制

ORA-0051

Timeout-on-resource

在等待資源時發生超時

ORA-0061

Transaction-backed-out

由於發生死鎖事務被撤消

ORA-1001

Invalid-CURSOR

試圖使用一個無效的遊標

ORA-1012

Not-logged-on

沒有連接到ORACLE

ORA-1017

Login-denied

無效的用戶名/口令

ORA-1403

No_data_found

SELECT INTO沒有找到數據

ORA-1422

Too_many_rows

SELECT INTO 返回多行

ORA-1476

Zero-divide

試圖被零除

ORA-1722

Invalid-NUMBER

轉換一個數字失敗

ORA-6500

Storage-error

內存不夠引發的內部錯誤

ORA-6501

Program-error

內部錯誤

ORA-6502

Value-error

轉換或截斷錯誤

ORA-6504

Rowtype-mismatch

宿主遊標變量與 PL/SQL變量有不兼容行類型

ORA-6511

CURSOR-already-OPEN

試圖打開一個已處於打開狀態的遊標

ORA-6530

Access-INTO-null

試圖爲null 對象的屬性賦值

ORA-6531

Collection-is-null

試圖將Exists 以外的集合( collection)方法應用於一個null pl/sql 表上或varray

ORA-6532

Subscript-outside-limit

對嵌套或varray索引得引用超出聲明範圍以外

ORA-6533

Subscript-beyond-count

對嵌套或varray 索引得引用大於集合中元素的個數.

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章