Procedural Language和SQL的結合體。通過增加變量、控制語句,使我們可以寫些邏輯更加復雜的數據庫操作
語句框架組成
declare – 可選 聲明各種變量或游標的地方。 begin – 必要 開始執行語句。 --單行注釋語句用兩個連在一起的‘-’表示。 /*多行注釋語句, 可以換行*/ exception – 可選 出錯后的處理。 end; – 必要(請注意end后面的分號)
簡單helloworld程序
1 declare 2 v_temp number(6):=123; /* := 是一個賦值符號 */ 3 begin 4 dbms_output.put_line('middle'); 5 dbms_output.put_line(v_temp); 6 end;
注意
要想顯示程序的東西需要設置環境
set serveroutput off -->關閉輸出(默認關閉) set serveroutput on -->打開輸出
基本數據類型
-
- Number 數字型
- Int 整數型
- Pls_integer 整數型,產生溢出時出現錯誤
- Binary_integer 整數型,表示帶符號的整數
- Char 定長字符型,最大255個字符
- Varchar2 變長字符型,最大2000個字符
- Long 變長字符型,最長2GB
- Date 日期型
- Boolean 布爾型(TRUE、FALSE、NULL三者取一)
- %type 表示不需要知道具體的一個字段類型,與指定的字段類型一致即可。例如:v_empno emp.empno%type;
-
%rowtype 與表結構完全一致 %rowtype 舉例:
1 declare 2 v_tt emp%rowtype; 3 begin 4 select * into v_tt from emp where empno=7521; 5 dbms_output.put_line(v_tt.job); 6 dbms_output.put_line(v_tt.sal); 7 end; 8 9 輸出:SALESMAN 10 1250
varray
定義語法
TYPE VARRAYNAMEIS VARRAY(SIZE) OF ELEMENTTYPE [NOT NULL];
-
-
其中,varrayname是VARRAY數據類型的名稱,size是正整數,表示可以容納的成員的最大數量,每個成員的數據類型是elementtypeo默認時,成員可以取空值,否則需要使用NOT NULL加以限制。
-
數組是具有相同數據類型的一組成員的集合。每個成員都有一個唯一的下標,它取決於成員在數組中的位置。在PL/SQL中,數組數據類型是VARRAY(variable array,即可變數組)。
-
1 declare 2 type my_varray is varray(2) of varchar2(12) not null; 3 varray_my my_varray; 4 begin 5 varray_my:=my_varray('dsa','sdafds'); 6 dbms_output.put_line(varray_my(1)); 7 end;
-
-
如果初始化數量大於設定的大小,會報下標超出限制異常
-
如果初始化數量小於設定的大小,會按照初始化數量進行設定大小,訪問不存在數據的下標(即使在設定范圍內).也會報異常
-
1 DECLARE 2 --定義一個最多保存5個VARCHAR(25)數據類型成員的VARRAY數據類型 3 TYPE reg_varray_type IS VARRAY(5) OF VARCHAR(25); 4 --聲明一個該VARRAY數據類型的變量 5 v_reg_varray REG_VARRAY_TYPE; 6 BEGIN 7 --用構造函數語法賦予初值 8 v_reg_varray := reg_varray_type 9 ('中國', '美國', '英國', '日本', '法國'); 10 DBMS_OUTPUT.PUT_LINE('地區名稱:'||v_reg_varray(1)||'、' 11 ||v_reg_varray(2)||'、' 12 ||v_reg_varray(3)||'、' 13 ||v_reg_varray(4)); 14 DBMS_OUTPUT.PUT_LINE('賦予初值NULL的第5個成員的值:'||v_reg_varray(5)); 15 --用構造函數語法賦予初值后就可以這樣對成員賦值 16 v_reg_varray(5) := '法國'; 17 DBMS_OUTPUT.PUT_LINE('第5個成員的值:'||v_reg_varray(5)); 18 END;
table
-
- 定義記錄表(或索引表)數據類型。它與記錄類型相似,但它是對記錄類型的擴展。它可以處理多行記錄,類似於C語言中的二維數組,使得可以在PL/SQL中模仿數據庫中的表。
定義記錄表類型的語法如下:
TYPE TABLE NAME IS TABLE OF ELEMENT_TYPE [NOT NULL] INDEX BY [BINARYINTEGER|LSINTEGER|VARRAY2];
-
- 關鍵字INDEX BY表示創建一個主鍵索引,以便引用記錄表變量中的特定行。 BINARY_INTEGER的說明
- 如語句:TYPE NUMBERS IS TABLE OF NUMBER INDEX BY BINARYINTEGER;其作用是,加”INDEX BYBINARYINTEGER ”后,NUMBERS類型的下標就是自增長,NUMBERS類型在插入元素時,不需要初始化,不需要每次EXTEND增加一個空間。
-
而如果沒有這句話“INDEXBY BINARY_INTEGER”,那就得要顯示對初始化,且每插入一個元素到NUMBERS類型的TABLE中時,都需要先EXTEND。
1 --table 不能像varray一樣初始化數據,只能一個一個賦值 2 declare 3 type table_my is table of number not null index by binary_integer;-- by binary_integer表示創建一個主鍵索引,以便引用記錄表變量中的特定行。 4 my_table table_my; 5 begin 6 my_table(1):=23; 7 my_table(2):=24; 8 my_table(3):=24; 9 dbms_output.put_line(my_table(1)); 10 end; 11 12 結果: 23 13 14 15 ---table結合rowtype的使用 16 declare 17 type table_my is table of emp%rowtype index by binary_integer; 18 19 my_table table_my; 20 begin 21 select * BULK COLLECT into my_table from emp ; 22 for i in my_table.first..my_table.last loop 23 dbms_output.put_line(my_table(i).empno||'=='||my_table(i).ename||'=='||my_table(i).job); 24 end loop; 25 end; 26 27 結果:1357==oracle== 28 7369==SMITH==CLERK 29 7499==ALLEN==SALESMAN 30 ...
table常見方法
record
-
- 定義記錄數據類型。它類似於C語言中的結構數據類型(STRUCTURE),PL/SQL提供了將幾個相關的、分離的、基本數據類型的變量組成一個整體的方法,即RECORD復合數據類型。在使用記錄數據類型變量時,需要在聲明部分先定義記錄的組成、記錄的變量,然后在執行部分引用該記錄變量本身或其中的成員。
定義記錄數據類型的語法如下:
TYPE RECORDNAME IS RECORD(
V1 DATATYPE1 [NOT NULL][:=DEFAULTVALUE],
V2 DATATYPE2 [NOT NULL][:=DEFAULTVALUE],
VN DATATYPEN [NOT NULL][:=DEFAULT_VALUE]
);
1 ---record實現多列多行查詢 2 declare 3 type my_record is record( 4 v_empno emp.empno%type, 5 v_ename emp.ename%type, 6 v_job emp.job%type 7 ); 8 type my_table is table of my_record index by binary_integer; 9 table_my my_table; 10 begin 11 select empno,ename,job BULK COLLECT into table_my from emp ; 12 for i in table_my.first..table_my.last loop 13 dbms_output.put_line(table_my(i).v_empno||'=='||table_my(i).v_ename||'=='||table_my(i).v_job); 14 end loop; 15 end; 16 結果同上一個table
boolean
-
- 布爾值只有TRUE, FALSE及 NULL 三個值
單行取值select
語法格式
select 字段 into 變量 from 表 where 條件
-
- 將查詢到得數據放入變量中
- 確保必須有唯一一個字段
- 不能存在多個值,也不能為空,否則報錯
- 將查詢到得數據放入變量中
異常處理,一級自定義異常
語法格式
EXCEPTION
WHEN firstexception THEN code to handle first exception
WHEN secondexception THEN code to handle second exception
WHEN OTHERS THEN code to handle others exception
END;
-
- 異常處理可以按任意次序排列,但 OTHERS 必須放在最后
常見異常
自定義異常:
1 declare 2 v_exception exception; 3 v_sal emp.sal%type; 4 begin 5 select sal into v_sal from emp where empno=7521; 6 if v_sal>1000 then 7 raise v_exception; 8 else 9 dbms_output.put_line('還可以'); 10 end if; 11 exception 12 when v_exception then 13 dbms_output.put_line('錢太少啦'); 14 end; 15 16 結果:錢太少啦
自定義錯誤----------------
1 declare 2 v_sal emp.sal%type; 3 begin 4 select sal into v_sal from emp where empno=7521; 5 if v_sal>1000 then 6 raise_application_error('-20000','工資太低啦'); 7 else 8 dbms_output.put_line(v_sal); 9 end if; 10 11 end; 12 結果:會彈出彈出框錯誤
PLSQL嵌套DML的 insert update delete
- 直接使用
- DML語句起作用或者回退的話,需要顯式的調用commit或者rollback
- sql%rowcount屬性來記錄最后一條SQL語句影響了多少 條記錄
insert
1 declare 2 v_empno emp.empno%type:=&s_empno; 3 begin 4 insert into emp(empno,ename) values(v_empno,'張三'); 5 if v_empno>4 then 6 rollback; 7 raise_application_error('-20000','不能這樣插滴~~'); 8 end if; 9 end; 10 結果彈出錯誤.
update和delete用法同上
execute immediate的用法
-
- 拼接字符串:標准的sql語句
- execute immediate +字符串
- execute immediate +字符串 into 變量 using 參數
- execute immediate 執行ddl語句或dml語句或dcl語句 (標准的sql語句)
1 ----1--- 2 declare 3 v_sql varchar2(122):='insert into emp(empno,ename) values(:a,:b)'; 4 begin 5 execute immediate v_sql using 111,'shfdk'; 6 commit; 7 end; 8 9 ----2----- 10 declare 11 v_sql varchar2(122) := 'select ename from emp where sal=:a'; 12 v_name emp.ename%type; 13 begin 14 execute immediate v_sql 15 into v_name 16 using 800; 17 dbms_output.put_line(v_name); 18 end;
循環結構
when
1 打印偶數 2 declare 3 v_num number(3, 0) := 0; 4 begin 5 loop 6 dbms_output.put_line(v_num); 7 v_num := v_num + 2; 8 exit when v_num = 100; 9 end loop; 10 end;
for循環
1 打印乘法口訣表 2 begin 3 for i in 1..9 loop 4 for j in 1..i loop 5 dbms_output.put(j||'*'||i||'='||(i*j)||chr(9)); 6 if i=j then dbms_output.new_line(); 7 end if; 8 end loop; 9 end loop; 10 end;