PL/SQL編程基礎


 

范例:編寫不做任何工作的PL/SQL

BEGIN

NULL ;

END ;

/

 

范例:編寫一個簡單的PL/SQL程序

DECLARE

v_num NUMBER ; -- 定義一個變量v_num

BEGIN

v_num := 30 ; -- 設置v_num的內容

DBMS_OUTPUT.put_line('V_NUM變量的內容是:' || v_num) ;

END ;

/

 

 

范例:編寫PL/SQL塊,輸入一個雇員編號,而后取得指定的雇員姓名

DECLARE

v_eno NUMBER ;

v_ename VARCHAR2(10) ;

BEGIN

v_eno := &empno ; -- 由鍵盤輸入雇員編號

SELECT ename INTO v_ename FROM emp WHERE empno=v_eno ;

DBMS_OUTPUT.put_line('編號為:' || v_eno || '雇員的名字為:'|| v_ename) ;

END ;

/

 

范例:定義變量不設置默認值

DECLARE

v_result VARCHAR2(30) ; -- 此處沒有賦值

BEGIN

DBMS_OUTPUT.put_line('v_result的內容〖' || v_result || '') ;

END ;

/

 

范例:定義變量

DECLARE

v_resultA NUMBER := 100 ; -- 定義一個變量同時賦值

v_resultB NUMBER ; -- 定義一個變量沒有設置內容

BEGIN

v_resultb := 30 ; -- 沒有區分大小寫

DBMS_OUTPUT.put_line('計算的結果是:' || (v_resultA + v_resultB) ) ;

END ;

/

 

范例:定義非空變量

DECLARE

v_resultA NUMBER NOT NULL := 100 ;  -- 定義一個非空變量v_resultA,同時賦值

BEGIN

DBMS_OUTPUT.put_line('v_resultA變量內容:' || (v_resultA) ) ;

END ;

/

 

范例:定義常量

DECLARE

v_resultA CONSTANT NUMBER NOT NULL := 100 ;  -- 定義一個常量同時賦值

BEGIN

DBMS_OUTPUT.put_line('v_resultA常量內容:' || (v_resultA) ) ;

END ;

/

 

范例:使用“%TYPE”定義變量

變量與指定的列的類型一致 采用%TYPE%

DECLARE

v_eno emp.empno%TYPE ; -- empno類型相同

v_ename emp.ename%TYPE ;  -- ename類型相同

BEGIN

DBMS_OUTPUT.put_line('請輸入雇員編號:') ;

v_eno := &empno ; -- 由鍵盤輸入雇員編號

SELECT ename INTO v_ename FROM emp WHERE empno= v_eno ;

DBMS_OUTPUT.put_line('編號為:' || v_eno || '雇員的名字為:'|| v_ename) ;

END ;

/

 

范例:使用ROWTYPE裝載

select into講表中的一行記錄設置到ROWTYPE類型的變量v_deptRow

可以使用v_deptRow. 出字段數據

DECLARE

v_deptRow dept%ROWTYPE ; -- 裝載一行dept記錄

BEGIN

SELECT * INTO v_deptRow FROM dept WHERE deptno=10 ;

DBMS_OUTPUT.put_line('部門編號:'|| v_deptRow.deptno || ',名稱:' || v_deptRow.dname || ',位置:' || v_deptRow.loc) ;

END ;

/

 

范例:通過自定義類型接收一行記錄

DECLARE

TYPE dept_type IS RECORD (

dno dept.deptno%TYPE ,

dna dept.dname%TYPE ,

dlo dept.loc%TYPE) ; -- 定義一個新的類型

v_deptRow dept_type ; -- 裝載一行dept記錄

BEGIN

SELECT * INTO v_deptRow FROM dept WHERE deptno=10 ;

DBMS_OUTPUT.put_line('部門編號:'|| v_deptRow.dno || ',名稱:' || v_deptRow.dna || ',位置:' || v_deptRow.dlo) ;

END ;

/

 

賦值運算符的主要功能是將一個數值賦予指定數據類型的變量,在之前聲明變量時已經使用此運算符,其使用語法如下所示。 變量 := 表達式 ;

范例:使用賦值運算符

將一個數值賦予指定數據類型的變量

DECLARE

v_info VARCHAR2(50) := '北京魔樂科技軟件學院' ;

v_url VARCHAR2(50) ;

BEGIN

v_url := 'www.mldnjava.cn' ;

DBMS_OUTPUT.put_line(v_info) ;

DBMS_OUTPUT.put_line(v_url) ;

END ;

/

 

范例:字符串連接 使用||

DECLARE

v_info VARCHAR2(50) := '北京魔樂科技軟件學院' ;

v_url VARCHAR2(50) ;

BEGIN

v_url := 'www.mldnjava.cn' ;

DBMS_OUTPUT.put_line(v_info || ',網址:' || v_url) ;

END ;

/

 

 

DECLARE

v_url VARCHAR2(50) := 'www.mldnjava.cn' ;

v_num1 NUMBER := 80 ;

v_num2 NUMBER := 30 ;

BEGIN

IF v_num1 > v_num2 THEN

DBMS_OUTPUT.put_line('1個數字比第2個數字大。') ;

END IF ;

IF v_url LIKE '%mldn%' THEN

DBMS_OUTPUT.put_line('網址之中包含mldn單詞。') ;

END IF ;

END ;

/

 

范例:觀察邏輯運算結果 IF  ENDIF

DECLARE

v_flag1 BOOLEAN := TRUE ;

v_flag2 BOOLEAN := FALSE ;

v_flag3 BOOLEAN ;

BEGIN

IF v_flag1 AND ( NOT v_flag2 ) THEN

DBMS_OUTPUT.put_line('v_flag1 AND ( NOT v_flag2 ) = TRUE') ;

END IF ;

IF v_flag1 OR v_flag3 THEN

DBMS_OUTPUT.put_line('v_flag1 OR v_flag3 = TRUE') ;

END IF ;

IF v_flag1 AND v_flag3 IS NULL THEN

DBMS_OUTPUT.put_line('v_flag1 AND v_flag3 的結果為NULL') ;

END IF ;

END ;

/

 

 

**********數據類型划分*********

 

 

范例:定義NUMBER變量

DECLARE

v_x NUMBER(3) ; -- 最多只能為3位數字

v_y NUMBER(5,2) ; -- 3位整數,2位小數

BEGIN

v_x := -500 ;

v_y := 999.88 ;

DBMS_OUTPUT.put_line('v_x = ' || v_x) ;

DBMS_OUTPUT.put_line('v_y = ' || v_y) ;

DBMS_OUTPUT.put_line('加法運算:' || (v_x + v_y)) ; -- 整數 + 浮點數 = 浮點數

END ;

/

 

范例:驗證PLS_INTEGER操作

BINARY_INTEGER PLS_INTERGER -2147483648~2147483647 2進制

相比NUMBER占用范圍更小,NUMBER為十進制 所以NUMBER相比性能低

當保存的數超出BINARY_INTEGER PLS_INTERGER范圍時會轉以NUMBER保存

DECLARE

v_pls1 PLS_INTEGER := 100 ;

v_pls2 PLS_INTEGER := 200 ;

v_result PLS_INTEGER ;

BEGIN

v_result := v_pls1 + v_pls2 ;

DBMS_OUTPUT.put_line('計算結果:' || v_result) ;

END ;

/

 

范例:驗證BINARY_DOUBLE操作

BINARY_FLOATBINARY_DOUBLENUMBER節約空間並且范圍更大

使用2進制保存數據,性能高

DECLARE

v_float BINARY_FLOAT := 8909.51F ;

v_double BINARY_DOUBLE := 8909.51D ;

BEGIN

v_float := v_float + 1000.16 ;

v_double := v_double + 1000.16 ;

DBMS_OUTPUT.put_line('BINARY_FLOAT變量內容:' || v_float) ;

DBMS_OUTPUT.put_line('BINARY_DOUBLE變量內容:' || v_double) ;

END ;

/

 

范例:觀察表示范圍的常量內容

DECLARE

BEGIN

DBMS_OUTPUT.put_line('1BINARY_FLOAT_MIN_NORMAL = ' || BINARY_FLOAT_MIN_NORMAL) ;

DBMS_OUTPUT.put_line('1BINARY_FLOAT_MAX_NORMAL = ' || BINARY_FLOAT_MAX_NORMAL) ;

DBMS_OUTPUT.put_line('1BINARY_FLOAT_MIN_SUBNORMAL = ' || BINARY_FLOAT_MIN_SUBNORMAL) ;

DBMS_OUTPUT.put_line('1BINARY_FLOAT_MAX_SUBNORMAL = ' || BINARY_FLOAT_MAX_SUBNORMAL) ;

DBMS_OUTPUT.put_line('2BINARY_DOUBLE_MIN_NORMAL = ' || BINARY_DOUBLE_MIN_NORMAL) ;

DBMS_OUTPUT.put_line('2BINARY_DOUBLE_MAX_NORMAL = ' || BINARY_DOUBLE_MAX_NORMAL) ;

DBMS_OUTPUT.put_line('2BINARY_DOUBLE_MIN_SUBNORMAL = ' || BINARY_DOUBLE_MIN_SUBNORMAL) ;

DBMS_OUTPUT.put_line('2BINARY_DOUBLE_MAX_SUBNORMAL = ' || BINARY_DOUBLE_MAX_SUBNORMAL) ;

END ;

/

 

范例:超過范圍的計算

DECLARE

BEGIN

DBMS_OUTPUT.put_line('超過范圍計算的結果:' ||

BINARY_DOUBLE_MAX_NORMAL * BINARY_DOUBLE_MAX_NORMAL) ;

DBMS_OUTPUT.put_line('超過范圍計算的結果:' ||

BINARY_DOUBLE_MAX_NORMAL / 0) ;

END ;

/

 

**********字符型*********

范例:觀察CHARVARCHAR2的區別

char定長 varchar2變長

oracle,VARCHAR2就是其他數據庫的varchar

DECLARE

v_info_char CHAR(10) ;

v_info_varchar VARCHAR2(10) ;

BEGIN

v_info_char := 'MLDN' ; -- 長度不足10

v_info_varchar := 'java' ; -- 長度不足10

DBMS_OUTPUT.put_line('v_info_char內容長度:' || LENGTH(v_info_char)) ;

DBMS_OUTPUT.put_line('v_info_varchar內容長度:' || LENGTH(v_info_varchar)) ;

END ;

/

 

 

范例:驗證NCHARNVARCHAR2

類似CHARVARCHAR2,但為UNICODE編碼  中英文都為十六進制保存

目的是統一了字符/英文的長度,也浪費了空間

DECLARE

v_info_nchar NCHAR(10) ;

v_info_nvarchar NVARCHAR2(10) ;

BEGIN

v_info_nchar := '魔樂科技' ; -- 長度不足10

v_info_nvarchar := 'java高端培訓' ; -- 長度不足10

DBMS_OUTPUT.put_line('v_info_nchar內容長度:' || LENGTH(v_info_nchar)) ;

DBMS_OUTPUT.put_line('v_info_nvarchar內容長度:' || LENGTH(v_info_nvarchar)) ;

END ;

/

 

范例:使用LONGLONG RAW操作

UTL_RAW.cast_to_raw(‘’字符串)

DECLARE

v_info_long LONG ;

v_info_longraw LONG RAW ;

BEGIN

v_info_long := '魔樂科技' ; -- 直接設置字符串

v_info_longraw := UTL_RAW.cast_to_raw('JAVA高端培訓') ; -- 將字符串變為RAW

DBMS_OUTPUT.put_line('v_info_long內容:' || v_info_long) ;

DBMS_OUTPUT.put_line('v_info_longraw內容:' || UTL_RAW.cast_to_varchar2(v_info_longraw)) ;

END ;

/

 

范例:使用ROWIDUROWID

DECLARE

v_emp_rowid ROWID ;

v_emp_urowid UROWID ;

BEGIN

SELECT ROWID INTO v_emp_rowid FROM emp WHERE empno=7369 ; -- 取得ROWID

SELECT ROWID INTO v_emp_urowid FROM emp WHERE empno=7369 ; -- 取得ROWID

DBMS_OUTPUT.put_line('7369雇員的ROWID = ' || v_emp_rowid) ;

DBMS_OUTPUT.put_line('7369雇員的UROWID = ' || v_emp_urowid) ;

END ;

/

 

 

***********日期類型***********

范例:定義DATE型變量

DECLARE

v_date1 DATE := SYSDATE ;

v_date2 DATE := SYSTIMESTAMP ;

v_date3 DATE := '19-9-1981' ;

BEGIN

DBMS_OUTPUT.put_line('日期數據:' || TO_CHAR(v_date1,'yyyy-mm-dd hh24:mi:ss')) ;

DBMS_OUTPUT.put_line('日期數據:' || TO_CHAR(v_date2,'yyyy-mm-dd hh24:mi:ss')) ;

DBMS_OUTPUT.put_line('日期數據:' || TO_CHAR(v_date3,'yyyy-mm-dd hh24:mi:ss')) ;

END ;

/

 

范例:定義TIMESTAMP型變量

DECLARE

v_timestamp1 TIMESTAMP := SYSDATE ;

v_timestamp2 TIMESTAMP := SYSTIMESTAMP ;

v_timestamp3 TIMESTAMP := '19-9-1981' ;

BEGIN

DBMS_OUTPUT.put_line('日期數據:' || v_timestamp1) ;

DBMS_OUTPUT.put_line('日期數據:' || v_timestamp2) ;

DBMS_OUTPUT.put_line('日期數據:' || v_timestamp3) ;

END ;

/

 

范例:驗證TIMESTAMP WITH TIME ZONE

DECLARE

v_timestamp TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP ;

BEGIN

DBMS_OUTPUT.put_line(v_timestamp) ;

END ;

/

 

范例:驗證TIMESTAMP WITH LOCAL TIME ZONE

DECLARE

v_timestamp TIMESTAMP WITH LOCAL TIME ZONE := SYSTIMESTAMP ;

BEGIN

DBMS_OUTPUT.put_line(v_timestamp) ;

END ;

/

 

范例:定義INTERVAL YEAR TO MONTHS類型變量

DECLARE

v_interval INTERVAL YEAR(3) TO MONTH := INTERVAL '27-09' YEAR TO MONTH ;

BEGIN

DBMS_OUTPUT.put_line('時間間隔:' || v_interval) ;

DBMS_OUTPUT.put_line('當前時間戳 + 時間間隔:' || (SYSTIMESTAMP + v_interval)) ;

DBMS_OUTPUT.put_line('當前日期 + 時間間隔:' || (SYSDATE + v_interval)) ;

END ;

/

 

范例:定義INTERVAL DAY TO SECOND類型變量

DECLARE

v_interval INTERVAL DAY(6) TO SECOND (3) := INTERVAL '8 18:19:27.367123909' DAY TO SECOND;

BEGIN

DBMS_OUTPUT.put_line('時間間隔:' || v_interval) ;

DBMS_OUTPUT.put_line('當前時間戳 + 時間間隔:' || (SYSTIMESTAMP + v_interval)) ;

DBMS_OUTPUT.put_line('當前日期 + 時間間隔:' || (SYSDATE + v_interval)) ;

END ;

/

 

范例:定義布爾型變量

DECLARE

v_flag BOOLEAN ;

BEGIN

v_flag := true ;

IF v_flag THEN

DBMS_OUTPUT.put_line('條件滿足。') ;

END IF ;

END ;

/

 

范例:定義NUMBER子類型

DECLARE

SUBTYPE score_subtype IS NUMBER(5,2) NOT NULL ;

v_score score_subtype := 99.35 ;

BEGIN

DBMS_OUTPUT.put_line('成績為:' || v_score) ;

END ;

/

 

范例:定義VARCHAR2子類型

DECLARE

SUBTYPE string_subtype IS VARCHAR2(200) ;

v_company string_subtype ;

BEGIN

v_company := '北京魔樂科技軟件學院(www.mldnjava.cn' ;

DBMS_OUTPUT.put_line(v_company) ;

END ;

/

 

 

 

**********分支結構***********

 

范例:IF語句

DECLARE

v_countResult NUMBER ;

BEGIN

SELECT COUNT(empno) INTO v_countResult FROM emp ;

IF v_countResult > 10 THEN

DBMS_OUTPUT.put_line('EMP表的記錄大於10條。') ;

END IF ;

END ;

/

 

范例:IF…ELSE語句

DECLARE

v_countResult NUMBER ;

BEGIN

SELECT COUNT(deptno) INTO v_countResult FROM dept ;

IF v_countResult > 10 THEN

DBMS_OUTPUT.put_line('DEPT表的記錄大於10條。') ;

ELSE

DBMS_OUTPUT.put_line('DEPT表的記錄小於10條。') ;

END IF ;

END ;

/

 

范例:IF…ELSIF…ELSE語句

DECLARE

v_countResult NUMBER ;

BEGIN

SELECT COUNT(empno) INTO v_countResult FROM emp ;

IF v_countResult > 10 THEN

DBMS_OUTPUT.put_line('EMP表的記錄大於10條。') ;

ELSIF v_countResult < 10 THEN

DBMS_OUTPUT.put_line('EMP表的記錄小於10條。') ;

ELSE

DBMS_OUTPUT.put_line('EMP表的記錄等於10條。') ;

END IF ;

END ;

/

 

范例:查詢emp表的工資,輸入員工編號,根據編號查詢工資,如果工資高於3000元,則顯示高工資,如果工資大於2000元,則顯示中等工資,如果工資小於2000元,則顯示低工資。

DECLARE

v_empSal emp.sal%TYPE ; -- 定義變量與emp.sal字段類型相同

v_empName emp.ename%TYPE ; -- 定義變量與emp.ename字段類型相同

v_eno emp.empno%TYPE ; -- 定義變量與emp.empno字段類型相同

BEGIN

v_eno := &inputEmpno; -- 用戶輸入要查找的雇員編號

-- 根據輸入的雇員編號查找雇員姓名及工資

SELECT ename,sal INTO v_empName,v_empSal FROM emp WHERE empno=v_eno;

IF v_empSal > 3000 THEN -- 判斷

DBMS_OUTPUT.put_line(v_empName || '的工資屬於高工資!') ;

ELSIF v_empSal > 2000 THEN -- 判斷

DBMS_OUTPUT.put_line(v_empName || '的工資屬於中等工資!') ;

ELSE

DBMS_OUTPUT.put_line(v_empName || '的工資屬於低工資!') ;

END IF;

END;

/

 

范例:用戶輸入一個雇員編號,根據它所在的部門給上漲工資,規則:

· 10部門上漲10%20上漲20%30上漲30%

· 但是要求最高不能超過5000,超過5000就停留在5000

DECLARE

v_empSal emp.sal%TYPE ; -- 定義變量與emp.sal字段類型相同

v_dno emp.deptno%TYPE ; -- 定義變量與emp.deptno字段類型相同

v_eno emp.empno%TYPE ; -- 定義變量與emp.empno字段類型相同

BEGIN

v_eno := &inputEmpno; -- 用戶輸入要查找的雇員編號

SELECT deptno,sal INTO v_dno, v_empSal FROM emp WHERE empno = v_eno ;

IF v_dno = 10 THEN

IF v_empSal * 1.1 > 5000 THEN

UPDATE emp SET sal=5000 WHERE empno=v_eno;

ELSE

UPDATE emp SET sal=sal*1.1 WHERE empno=v_eno;

END IF;

ELSIF v_dno = 20 THEN

IF v_empSal * 1.2 > 5000 THEN

UPDATE emp SET sal =5000 WHERE empno=v_eno;

ELSE

UPDATE emp SET sal=sal*1.2 WHERE empno=v_eno;

END IF;

ELSIF v_dno = 30 THEN

IF v_empSal * 1.3 > 5000 THEN

UPDATE emp SET sal=5000 WHERE empno=v_eno;

ELSE

UPDATE emp SET sal=sal*1.3 WHERE empno=v_eno;

END IF;

ELSE

null;

END IF;

END;

/

 

范例:正則驗證

DECLARE

v_str VARCHAR2(50) := '123' ;

BEGIN

IF REGEXP_LIKE(v_str,'^\d+$') THEN

DBMS_OUTPUT.put_line('正則驗證通過。') ;

END IF ;

END ;

/

 

范例:驗證AND操作符

BEGIN

IF 'MLDN' = 'MLDN' AND 100 = 100 THEN

DBMS_OUTPUT.put_line('結果為TRUE,滿足條件!') ;

END IF ;

END;

/

 

范例:驗證BETWEEN…AND

BEGIN

IF TO_DATE('1983-09-19','yyyy-mm-dd') BETWEEN  TO_DATE('1980-01-01','yyyy-mm-dd')

AND TO_DATE('1989-12-31','yyyy-mm-dd') THEN

DBMS_OUTPUT.put_line('您俗稱80后!') ;

END IF ;

END;

/

 

范例:驗證IN操作符

BEGIN

IF 10 IN (10,20,30) THEN

DBMS_OUTPUT.put_line('數據已成功查找到') ;

END IF ;

END;

/

 

范例:驗證IS NULL

DECLARE

v_temp BOOLEAN ; -- 定義布爾變量,沒有設置內容

BEGIN

IF v_temp IS NULL THEN

DBMS_OUTPUT.put_line('v_temp變量的內容是null') ;

END IF ;

END;

/

 

范例:驗證LIKE操作符

BEGIN

IF 'www.mldnjava.cn' LIKE '%mldn%' THEN

DBMS_OUTPUT.put_line('可以查找到字符串:mldn') ;

END IF ;

END;

/

 

范例:驗證NOT操作符

BEGIN

IF NOT FALSE THEN

DBMS_OUTPUT.put_line('條件滿足,FALSE變為TRUE') ;

END IF ;

END;

/

 

范例:

BEGIN

IF 'MLDN' = 'LXH' OR 10 = 10 THEN

DBMS_OUTPUT.put_line('有一個條件滿足,返回TRUE') ;

END IF ;

END;

/

 

范例:使用CASE語句判斷數值

DECLARE

v_choose NUMBER := 1 ;

BEGIN

CASE v_choose

WHEN 0 THEN

DBMS_OUTPUT.put_line('您選擇的是第0項。') ;

WHEN 1 THEN

DBMS_OUTPUT.put_line('您選擇的是第1項。') ;

ELSE

DBMS_OUTPUT.put_line('沒有選項滿足。') ;

END CASE ;

END ;

/

 

范例:使用CASE進行多條件判斷

DECLARE

v_salary emp.sal%TYPE ;

v_eno emp.empno%TYPE ;

BEGIN

v_eno := &inputEmpno ;

SELECT sal INTO v_salary FROM emp WHERE empno=v_eno ;

CASE

WHEN v_salary >= 3000  THEN

DBMS_OUTPUT.put_line('雇員:' || v_eno || '的收入為高工資。') ;

WHEN v_salary >= 2000 AND v_salary <3000 THEN

DBMS_OUTPUT.put_line('雇員:' || v_eno || '的收入為中等工資。') ;

ELSE

DBMS_OUTPUT.put_line('雇員:' || v_eno || '的收入為低工資。') ;

END CASE ;

END ;

/

 

范例:輸入雇員編號,根據雇員的職位進行工資提升,提升要求如下

· 如果職位是辦事員(CLERK),工資增長5%

· 如果職位是銷售人員(SALESMAN),工資增長8%

· 如果職位為經理(MANAGER),工資增長10%

· 如果職位為分析員(ANALYST),工資增長20%

· 如果職位為總裁(PRESIDENT),工資不增長。

DECLARE

v_job emp.job%TYPE ;

v_eno emp.empno%TYPE ;

BEGIN

v_eno := &inputEmpno ;

SELECT job INTO v_job FROM emp WHERE empno=v_eno ;

CASE v_job

WHEN 'CLERK' THEN

UPDATE emp SET sal=sal*1.05 WHERE empno=v_eno ;

WHEN 'SALESMAN' THEN

UPDATE emp SET sal=sal*1.08 WHERE empno=v_eno ;

WHEN 'MANAGER' THEN

UPDATE emp SET sal=sal*1.10 WHERE empno=v_eno ;

WHEN 'ANALYST' THEN

UPDATE emp SET sal=sal*1.20 WHERE empno=v_eno ;

ELSE

DBMS_OUTPUT.put_line('雇員:' || v_eno || '工資不具備上漲資格!') ;

END CASE ;

END ;

/

 

范例:使用LOOP循環

EXIT WHEN結束循環

DECLARE

v_i NUMBER := 1 ; -- 定義一個變量,用於循環

BEGIN

LOOP

DBMS_OUTPUT.put_line('v_i = ' || v_i) ;

EXIT WHEN v_i >= 3 ;

v_i := v_i + 1 ;

END LOOP ;

END ;

/

 

范例:使用WHILE…LOOP循環

DECLARE

v_i NUMBER := 1 ; -- 定義一個變量,用於循環

BEGIN

WHILE (v_i <= 3) LOOP

DBMS_OUTPUT.put_line('v_i = ' || v_i) ;

v_i := v_i + 1 ;

END LOOP ;

END ;

/

 

范例:使用FOR循環

DECLARE

v_i NUMBER := 1 ; -- 定義一個變量,用於循環

BEGIN

FOR v_i IN 1 .. 3 LOOP

DBMS_OUTPUT.put_line('v_i = ' || v_i) ;

END LOOP ;

END ;

/

 

范例:使用REVERSE操作

DECLARE

v_i NUMBER := 1 ; -- 定義一個變量,用於循環

BEGIN

FOR v_i IN REVERSE 1 .. 3 LOOP

DBMS_OUTPUT.put_line('v_i = ' || v_i) ;

END LOOP ;

END ;

/

 

范例:使用EXIT結束循環操作

DECLARE

v_i NUMBER := 1 ; -- 定義一個變量,用於循環

BEGIN

FOR v_i IN 1 .. 10 LOOP

IF v_i = 3 THEN -- v_i變量增長到3時結束循環

EXIT ;

END IF ;

DBMS_OUTPUT.put_line('v_i = ' || v_i) ;

END LOOP ;

END ;

/

 

范例:使用CONTINUE控制循環操作(結束當前的循環)

DECLARE

v_i NUMBER := 1 ; -- 定義一個變量,用於循環

BEGIN

FOR v_i IN 1 .. 10 LOOP

IF MOD(v_i,2) = 0 THEN -- 為偶數的時候不執行后續方法體

CONTINUE ;

END IF ;

DBMS_OUTPUT.put_line('v_i = ' || v_i) ;

END LOOP ;

END ;

/

 

范例:使用GOTO進行跳轉

DECLARE

v_result NUMBER := 1;

BEGIN

FOR v_result IN 1 .. 10 LOOP

IF v_result = 2 THEN

GOTO endPoint ;

END IF ;

DBMS_OUTPUT.put_line('v_result = ' || v_result) ;

END LOOP ;

<<endPoint>>

DBMS_OUTPUT.put_line('FOR循環提前結束。') ;

END ;

/

 

范例:定義內部程序塊

DECLARE

v_x NUMBER := 30 ; -- 此為全局變量

BEGIN

DECLARE

v_x VARCHAR2(40) := 'MLDNJAVA' ; -- 此為局部變量,只能在內部程序塊中使用

v_y NUMBER := 20 ;

BEGIN

DBMS_OUTPUT.put_line('內部程序塊輸出:v_x = ' || v_x) ;

DBMS_OUTPUT.put_line('內部程序塊輸出:v_y = ' || v_y) ;

END ;

DBMS_OUTPUT.put_line('外部程序塊輸出:v_x = ' || v_x) ;

END ;

/

 

范例:程序語法錯誤

DECLARE

v_result NUMBER := 1 ;

BEGIN

IF v_result = 1-- 此處語法有錯誤,缺少THEN

DBMS_OUTPUT.put_line('條件滿足。') ;

END IF ;

END ;

/

 

范例:運行時異常

DECLARE

v_result NUMBER ;

BEGIN

v_result := 10/0 ; -- 被除數為0

END ;

/

 

 

 

范例:處理被除數為零異常

DECLARE

v_result NUMBER ;

BEGIN

v_result := 10/0 ; -- 被除數為0

DBMS_OUTPUT.put_line('異常之后的代碼將不再執行!') ;

EXCEPTION

WHEN zero_divide THEN

DBMS_OUTPUT.put_line('被除數不能為零。') ;

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

END ;

/

 

范例:處理賦值異常

DECLARE

v_varA VARCHAR2(1) ;

v_varB VARCHAR2(4) := 'java' ;

BEGIN

v_varA := v_varB ; -- 錯誤的賦值

DBMS_OUTPUT.put_line('異常之后的代碼將不再執行!') ;

EXCEPTION

WHEN value_error THEN

DBMS_OUTPUT.put_line('數據賦值錯誤。') ;

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

END ;

/

 

范例:處理SQL異常 —— 找不到數據

DECLARE

v_eno emp.empno%TYPE ;

v_ename emp.ename%TYPE ;

BEGIN

v_eno := &empno ; -- 由鍵盤輸入雇員編號

SELECT ename INTO v_ename FROM emp WHERE empno=v_eno ;

DBMS_OUTPUT.put_line('編號為:' || v_eno || '雇員的名字為:' || v_ename) ;

EXCEPTION

WHEN no_data_found THEN

DBMS_OUTPUT.put_line('沒有這個雇員!') ;

END ;

/

 

 

范例:處理SQL異常 —— 返回多條結果

DECLARE

v_dno emp.deptno%TYPE ;

v_ename emp.ename%TYPE ;

BEGIN

v_dno := &deptno ; -- 由鍵盤輸入部門編號

SELECT ename INTO v_ename FROM emp WHERE deptno=v_dno ;

EXCEPTION

WHEN too_many_rows THEN

DBMS_OUTPUT.put_line('返回的數據過多!') ;

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

END ;

/

 

范例:使用others來捕獲所有異常

DECLARE

v_result NUMBER ;

v_title VARCHAR2(50) := 'www.mldnjava.cn' ;

BEGIN

v_result := v_title ;-- 此處出現異常

EXCEPTION

WHEN others THEN

DBMS_OUTPUT.put_line('返回的數據過多!') ;

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

DBMS_OUTPUT.put_line('SQLERRM = ' || SQLERRM) ;

END ;

/

 

 

范例:使用用戶定義異常

DECLARE

v_data NUMBER ;

v_myexp EXCEPTION ;

BEGIN

v_data := &inputData ;

IF v_data > 10 AND v_data < 100 THEN

RAISE v_myexp ; -- 拋出異常

END IF ;

EXCEPTION

WHEN others THEN

DBMS_OUTPUT.put_line('輸入數據有錯誤!') ;

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

DBMS_OUTPUT.put_line('SQLERRM = ' || SQLERRM) ;

END ;

/

 

范例:設置異常代碼

DECLARE

v_data NUMBER ;

v_myexp EXCEPTION ;

PRAGMA EXCEPTION_INIT(v_myexp , -20789) ;

BEGIN

v_data := &inputData ;

IF v_data > 10 AND v_data < 100 THEN

RAISE v_myexp ; -- 拋出異常

END IF ;

EXCEPTION

WHEN v_myexp THEN

DBMS_OUTPUT.put_line('輸入數據有錯誤!') ;

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

DBMS_OUTPUT.put_line('SQLERRM = ' || SQLERRM) ;

END ;

/

 

范例:綁定已有的錯誤號

DECLARE

v_myexp EXCEPTION ;

v_input_rowid VARCHAR2(18) ;

PRAGMA EXCEPTION_INIT(v_myexp , -01410) ;

BEGIN

v_input_rowid := '&inputRowid' ; -- 輸入一個ROWID

IF LENGTH(v_input_rowid) <> 18 THEN

RAISE v_myexp ;

END IF ;

EXCEPTION

WHEN v_myexp THEN

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

DBMS_OUTPUT.put_line('SQLERRM = ' || SQLERRM) ;

END ;

/

 

范例:構建動態異常

DECLARE

v_data NUMBER ;

v_myexpEXCEPTION ; -- 定義了一個異常變量

PRAGMA EXCEPTION_INIT(v_myexp , -20789) ;

BEGIN

v_data := &inputData ; -- 輸入數據

IF v_data > 10 AND v_data < 100 THEN

RAISE_APPLICATION_ERROR(-20789 , '輸入數字不能在10 ~ 100之間!') ;

END IF ;

EXCEPTION

WHEN v_myexp THEN -- 出現指定的異常

DBMS_OUTPUT.put_line('輸入數據有錯誤!') ;

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

DBMS_OUTPUT.put_line('SQLERRM = ' || SQLERRM) ;

END ;

/

 

范例:不聲明異常變量,直接構建異常,同時使用others捕獲

DECLARE

v_data NUMBER ;

v_myexp EXCEPTION ; -- 定義了一個異常變量

BEGIN

v_data := &inputData ; -- 輸入數據

IF v_data > 10 AND v_data < 100 THEN

RAISE_APPLICATION_ERROR(-20789 , '輸入數字不能在10 ~ 100之間!') ;

END IF ;

EXCEPTION

WHEN others THEN -- 出現指定的異常

DBMS_OUTPUT.put_line('輸入數據有錯誤!') ;

DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE) ;

DBMS_OUTPUT.put_line('SQLERRM = ' || SQLERRM) ;

END ;

/

 

范例:使用PL/SQL增加部門信息

DECLARE

v_dno dept.deptno%TYPE ; -- 部門編號

v_dna dept.dname%TYPE ; -- 部門名稱

v_dloc dept.loc%TYPE ; -- 部門位置

v_deptCount NUMBER ; -- 保存COUNT()函數結果

BEGIN

v_dno := &inputDeptno ; -- 輸入部門編號

v_dna := '&inputDname' ; -- 輸入部門名稱

v_dloc := '&inputLoc' ; -- 接收部門位置

-- 統計要增加的部門編號在dept表中的信息數量,如果返回0表示沒有此部門

SELECT COUNT(deptno) INTO v_deptCount FROM dept WHERE deptno=v_dno ;

IF v_deptCount > 0 THEN -- 部門存在

RAISE_APPLICATION_ERROR(-20888 , '此部門編號已存在,請重新輸入!') ;

ELSE -- 部門不存在

INSERT INTO dept(deptno,dname,loc) VALUES (v_dno,v_dna,v_dloc) ;

DBMS_OUTPUT.put_line('新部門增加成功!') ;

COMMIT ;

END IF ;

EXCEPTION

WHEN others THEN

DBMS_OUTPUT.put_line(SQLERRM) ;

ROLLBACK ;

END ;

/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM