范例:編寫不做任何工作的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_FLOAT和BINARY_DOUBLE比NUMBER節約空間並且范圍更大
使用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('1、BINARY_FLOAT_MIN_NORMAL = ' || BINARY_FLOAT_MIN_NORMAL) ; DBMS_OUTPUT.put_line('1、BINARY_FLOAT_MAX_NORMAL = ' || BINARY_FLOAT_MAX_NORMAL) ; DBMS_OUTPUT.put_line('1、BINARY_FLOAT_MIN_SUBNORMAL = ' || BINARY_FLOAT_MIN_SUBNORMAL) ; DBMS_OUTPUT.put_line('1、BINARY_FLOAT_MAX_SUBNORMAL = ' || BINARY_FLOAT_MAX_SUBNORMAL) ; DBMS_OUTPUT.put_line('2、BINARY_DOUBLE_MIN_NORMAL = ' || BINARY_DOUBLE_MIN_NORMAL) ; DBMS_OUTPUT.put_line('2、BINARY_DOUBLE_MAX_NORMAL = ' || BINARY_DOUBLE_MAX_NORMAL) ; DBMS_OUTPUT.put_line('2、BINARY_DOUBLE_MIN_SUBNORMAL = ' || BINARY_DOUBLE_MIN_SUBNORMAL) ; DBMS_OUTPUT.put_line('2、BINARY_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 ; / |
**********字符型*********
范例:觀察CHAR和VARCHAR2的區別
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 ; / |
范例:驗證NCHAR和NVARCHAR2
類似CHAR和VARCHAR2,但為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 ; / |
范例:使用LONG和LONG 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 ; / |
范例:使用ROWID及UROWID
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 ; / |