Oracle PL/SQL 程序設計基礎

最近項目在做版本升級,涉及到原有功能的表結構修改,需要將舊數據轉移到新庫中,項目上定的方案是在舊數據庫中通過存儲過程生成新數據庫的INSERT語句。故對此塊內容做了複習整理。


通過一個簡單的例子分析PL/SQL程序塊結構
在這裏插入圖片描述

  • 聲明部分
  • 執行部分
    • 用於執行各種對數據庫操作的語句和對異常進行處理的邏輯

聲明變量

--格式:變量名 數據類型;
v_name VARCHAR2(128);

聲明常量

--格式: 變量名 CONSTRANT 數據類型 := value;
v_days_in_year CONSTRANT INTEGER := 365;

PL/SQL 數據類型


執行部分邏輯是按從上到下的順序執行的,PL/SQL 支持條件選擇語句循環語句

IF 語句最簡形式

IF condition THEN
	DBMS_OUTPUT.PUT_LINE('當condition爲TRUE時,執行');
END IF;

IF 語句擴展形式

IF condition1 THEN
	DBMS_OUTPUT.PUT_LINE('當condition1爲TRUE時,執行');
ELSIF condition2 THEN
	DBMS_OUTPUT.PUT_LINE('當condition2爲TRUE時,執行');
ELSE
	DBMS_OUTPUT.PUT_LINE('當condition1爲FALSE且condition2爲FALSE時,執行');
END IF;

一個IF語句最多隻能有一個ELSE分支,可以有0個多個 ELSIF condition THEN分支

CASE 語句最簡形式

CASE age
	WHEN 10 THEN 
		DBMS_OUTPUT.PUT_LINE('當age值爲10時,執行');
END CASE;

CASE 語句擴展形式

CASE age
	WHEN 10 THEN
		DBMS_OUTPUT.PUT_LINE('當age值爲10時,執行');
	WHEN 20 THEN
		DBMS_OUTPUT.PUT_LINE('當age值爲20時,執行');
	WHEN 30 THEN
		DBMS_OUTPUT.PUT_LINE('當age值爲30時,執行');
	ELSE
		DBMS_OUTPUT.PUT_LINE('當age值爲其它值時,執行');		
END CASE;

一個CASE語句最多隻能有一個ELSE分支,可以有一個或多個WHEN THEN分支

CASE 語句變形

CASE
	WHEN age = 10 THEN
		DBMS_OUTPUT.PUT_LINE('當age值爲10時,執行');
	WHEN age = 20 THEN
		DBMS_OUTPUT.PUT_LINE('當age值爲20時,執行');
	WHEN age = 30 THEN
		DBMS_OUTPUT.PUT_LINE('當age值爲30時,執行');
	ELSE
		DBMS_OUTPUT.PUT_LINE('當age值爲其它值時,執行');		
END CASE;

CASE 語句賦值給變量,THEN後面的語句不要加;

appraisal :=
CASE
	WHEN grade = 'A' THEN '優'
	WHEN grade = 'B' THEN '良'
	WHEN grade = 'C' THEN '差'
	ELSE ''
END CASE;

LOOP

num NUMBER := 0;
total NUMBER := 0;
LOOP
	num := num + 1;
	total := total + num;
	EXIT WHEN num = 10;--當num=10時,退出循環
END LOOP;
	DBMS_OUTPUT.PUT_LINE(total);
--退出循環
EXIT WHEN condition;
--退出當前循環進入下一次循環
CONTINUE WHEN condition;

FOR

FOR item IN 1..10 LOOP
	DBMS_OUTPUT.PUT_LINE(item);
END LOOP;

每次迭代的步長都是1,當在IN關鍵字後面加上REVERSE關鍵字時,將反轉遍歷的順序,在上例中將變爲從10~1

WHILE

WHILE condition LOOP
	DBMS_OUTPUT.PUT_LINE();
	condition := FALSE;
END LOOP;

聲明記錄

--格式: 變量名 表名.字段名%TYPE;
v_name employee.name%TYPE;
--格式: 變量名 表名%ROWTYPE;
v_row employee%ROWTYPE;

表名.字段名%TYPE : 用於單個字段
表名%ROWTYPE : 用於表中的一行記錄
使用以上兩種方式定義變量的數據類型,使聲明的變量的數據類型將與指定表中指定的字段的數據類型始終保持一致

如果我們需要定義一個變量存儲多個字段(大於一個字段但小於表中的全部字段 或 多個字段來自多個表)的值時,我們可以聲明一個record type

TYPE employeeAddrType IS RECORD(
	name VARCHAR2(128),
	addr VARCHAR2(256)
);

v_employee_adr employeeAddrType;

遊標
遊標的使用由以下幾步操作構成:

  1. 聲明遊標
  2. 打開遊標
  3. 邏輯處理
  4. 關閉遊標
DECLARE
	--聲明遊標
	CURSOR my_cursor IS SELECT * FROM employee;
BEGIN
	--打開遊標
	OPEN my_cursor;
	--邏輯處理
	LOOP
		EXIT WHEN my_cursor%NOTFOUND;
		DBMS_OUTPUT.PUT_LINE(my_cursor.name);
	END LOOP;
	--關閉遊標
	CLOSE my_cursor;
END;

將遊標中的數據賦值到指定的變量中

FETCH my_cursor INTO v_row;

使用遊標更新數據時,在聲明遊標的結尾需要使用FOR UPDATE,例如:

CURSOR my_cursor IS SELECT * FROM employee FOR UPDATE;

在邏輯處理部分的UPDATE語句中使用WHERE CURRENT OF 遊標名指定更新當前行

UPDATE employee SET name = name||'TEST' WHERE CURRENT OF my_cursor;

如何傳參到遊標中呢?
在遊標聲明處指定參數,例如:

CURSOR my_cursor(v_id employee.id%TYPE) IS SELECT * FROM employee WHERE id=v_id;

聲明瞭變量後如何使用呢,在打開遊標處設置參數值

OPEN my_cursor(1);

過程

CREATE OR REPLACE PROCEDURE procedure_name
	IS
	--聲明變量
BEGIN
	--邏輯處理
END procedure_name;

上面的存儲過程是無參的,而實際工作中我們可能會遇到需要傳參或返回值的情況
參數有三種模式,分爲:

  • 輸入參數: in
  • 輸出參數: out
  • 輸入輸出參數: in out
    默認模式爲: in
CREATE OR REPLACE PROCEDURE procedure_name(
	business_type in varchar2(4),
	apply_code in varchar2(32),
	business_stauts out varchar2(4)
) IS
	--聲明變量
	v_business_status varchar2(4);
	v_sql varchar2(200);
BEGIN
	--邏輯處理
	v_sql := 'SELECT business_status INTO v_business_status FROM dp_c_business_apply where business_type = '''||business_type||''' and apply_code = '''||apply_code||'';'
	execute immediate v_sql;
	business_status := v_business_status;
END procedure_name;

調用存儲過程

DECLARE
v_status varchar2(200);
BEGIN
EXECUTE  procedure_name('BS01','201907200000001',v_status);
END;

在上面的例子中我們是按各參數的位置進行傳值的,我們還可以按參數名稱進行傳值

v_status varchar2(200);
BEGIN
EXECUTE  procedure_name(business_type=>'BS01',apply_code=>'201907200000001',business_status=>business_status);
END;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章