PL/SQL
PL/SQL是一種高級數據庫程序設計語言,該語言專門用於在各種環境下對ORACLE數據庫進行訪問。由
於該語言集成於數據庫服務器中,所以PL/SQL代碼可以對數據進行快速高效的處理。除此之外,可以在
ORACLE數據庫的某些客戶端工具中,使用PL/SQL語言也是該語言的一個特點。
PL/SQL是對SQL語言存儲過程語言的擴展。
PL/SQL程序由三個塊組成,即聲明部分,執行部分,異常處理部分。
declare
/*聲明部分 聲明PL/SQL用到的變量,類型及遊標,以及局部的存儲過程和函數*/
begin
/*執行部分 過程及SQL語句*/
exception
/*異常處理部分 錯誤處理*/
end;
其中執行部分是必須有的 (begin…..end;)
PL/SQL塊可以分爲三類
- 無名塊:動態構造,只能執行一次
- 子程序:存儲在數據庫中的存儲過程、函數及包等。在數據庫建立之後可在其他程序調用它們。
- 觸發器:當數據庫發生操作時,會觸發一些事件,從而自動執行相應的程序。
declare
v_name varchar2(20) := 'zhangsan';
v_age number := 33;
begin
dbms_output.put_line(v_name||' '||v_age);
end;
命名:
標識符 命名規則
程序變量 v_name
程序常量 c_name
記錄類型 name_record
遊標變量 name_cursor
異常標識 e_name
:= 賦值號 => 關係號
||連接字符 null+<數字>=null null+<字符串>=<字符串>
boolean : true,false,null
記錄類型
記錄類型是把邏輯相關的數據作爲一個單元存儲起來,稱爲PL/SQL record的域(field),其作用是存放互不相同但邏輯相關的信息。
記錄類型是把邏輯相關的數據作爲一個單元存儲起來,稱爲PL/SQL record的域(field),其作用是存放互不相同但邏輯相關的信息。
語法: (在 declare 中定義)
type name_record is record(
field1 type ( := exp1),
field2 type ( := exp2)
);
declare
type test_record is record(
v_name varchar2(20),
v_sal number
);
v_emp test_record;
v_id number := 100;
begin
select last_name,salary into v_emp from employees where employee_id=v_id;
dbms_output.put_line(v_emp.v_name||' id:'||v_id||' salary:'||v_emp.v_sal);
end;
%rowtype 各行數據類型
%type 對於數據類型
使用%rowtype 特性的優點在於:
所引用的數據庫中列的個數和數據類型可以不必知道
所引用的數據庫中列的個數和數據類型可以實時改變
declare
emp_record employees%rowtype;
v_id employees.employee_id%type := 100;
v_pay number;
begin
select * into emp_record from employees where employee_id=v_id;
dbms_output.put_line(emp_record.last_name||' id:'||emp_record.employee_id||' salary:'||emp_record.salary);
v_pay:=emp_record.salary*(1+emp_record.commission_pct);
---- number + null = null varchar2 + null = varchar2 ----------
dbms_output.put_line(v_pay);
dbms_output.put_line('voer!!!');
v_pay:=emp_record.salary*(1+nvl(emp_record.commission_pct,0));
dbms_output.put_line(v_pay);
dbms_output.put_line('really voer!!!');
end;
這裏注意1+emp_record.commission_pct與1+nvl(emp_record.commission_pct,0)結果的區別
– number + null = null varchar2 + null = varchar2
–if 條件 then
– sql 和 pl/sql
– end if;
declare
v_id employees.employee_id%type;
v_sal employees.salary%type;
v_comment varchar2(50);
begin
v_id := 104;
select salary into v_sal from employees where employee_id=v_id;
if v_sal<1500 then
v_comment := 'fairly less';
elsif v_sal<3000 then
v_comment :='a little more';
else
v_comment :='good';
end if;
dbms_output.put_line(v_comment);
end;
–case selector when 條件1 then 結果1
– when 條件2 then 結果2
– else 結果3
–end;
declare
v_garde char(1);
v_comment varchar2(50);
begin
v_garde := 'A';
v_comment:=
case v_garde when 'A' then 'excellent'
when 'B' then 'good'
else 'so so'
end;
dbms_output.put_line(v_comment);
end;
–loop
–要執行語句;
–exit when 條件; 條件滿足,立即直接退出循環
–end loop;
declare
i number :=0;
begin
loop
exit when i =10;
i := i+1;
dbms_output.put_line(i);
end loop;
end;
–whlie 條件 loop
– 要執行語句;
–end loop;
declare
i number := 0;
begin
while i <10 loop
i := i+1;
dbms_output.put_line(i);
end loop;
end;
–for 循環計數器 in (reverse)下限 .. 上限 loop
– 要執行語句;
–end loop;
–每循環一次,循環變量自動加1。in 後面的 下限,上限必須從小到大。可以使用exit退出循環
注意:for後面的循環變量相當於新聲明的變量,且可以和declare裏的同名,與declare裏的變量無關
declare
i number :=0;
minnum number :=3;
maxnum number :=7;
begin
dbms_output.put_line(i);
for i in minnum..maxnum loop
dbms_output.put_line(i);
end loop;
dbms_output.put_line(i);
--for後面的循環變量相當於新聲明的變量,且可以和declare裏的同名,與declare裏的變量無關
for ii in minnum..maxnum loop
dbms_output.put_line(i);
end loop;
end;
標號和GOTO
PL/SQL中的GOTO語句:無條件跳轉到指定的標號去
goto label;
……
<< label >>
declare
i number := 0;
begin
loop
i:=i+1;
dbms_output.put_line(i);
if i=10 then
goto test_label;
end if;
end loop;
<<test_label>>
dbms_output.put_line('end!!!');
end;
異常處理
異常情況處理(EXCEPTION)是用來處理正常執行過程中未預料的事件,程序塊的異常處理預定義的錯誤和自定義錯誤,由於 PL/SQL 程序塊一旦產生異常而沒有指出如何處理時,程序就會自動終止整個程序運行。
三種類型的異常錯誤
- 預定義錯誤
ORACLE 預定義的異常情況大約有 24 個。對這種異常情況的處理,無需在程序中定義,由 ORACLE 自動
將其引發。 - 非預定義錯誤
即其他標準的 ORACLE 錯誤。對這種異常情況的處理,需要用戶在程序中定義,然後由 ORACLE 自動將
其引發。 - 用戶定義錯誤
程序執行過程中,出現編程人員認爲的非正常情況。對這種異常情況的處理,需要用戶在程序中定義,
然後顯式地在程序中將其引發。
預定義錯誤處理:只需在 PL/SQL 塊的異常處理部分,直接引用相應的異常情況名
begin ....
exception
when no_data_found then dbms_output.put_line('沒找到數據');
when others then dbms_output.put_line('不明原因');
end;
非預定義錯誤處理:
1.在PL/SQL塊定義部分定義異常
異常名 exception;
2.將定義好的異常與標準的ORACLE錯誤聯繫起來
pragma exception_init ( 異常名, 錯誤代碼 );
3.在 PL/SQL 塊的異常處理部分對異常情況做出相應的處理
declare
v_deptno number :=&deptno;
deptno_remaining exception ;
pragma exception_init(deptno_remaining,-2292);
begin
delete from departments where department_id=v_deptno;
exception
when deptno_remaining then dbms_output.put_line('不讓刪');
when others then dbms_output.put_line('不明原因');
end;
用戶定義錯誤處理
1.在 PL/SQL 塊的定義部分定義異常情況:
異常名 exception;
2.raise 異常;
3.在 PL/SQL 塊的異常處理部分對異常情況做出相應的處理
declare
v_empno number := &empno;
no_result exception;
begin
update employees set salary=6666 where employee_id=v_empno;
if sql%notfound then
raise no_result;
end if;
exception
when no_result then dbms_output.put_line('沒找到員工');
when others then dbms_output.put_line('不明原因');
end;