PL/SQL語句塊基本語法(ORACLE存儲過程,函數,包,游標)
1、 PL/SQL語句塊
PL/SQL語句塊只適用於Oracle數據庫,使用時臨時保存在客戶端,而不是保存在數據庫。
基本語法:
declare
變量聲明、初始化
begin
業務處理、邏輯代碼
exception
異常捕獲
end;
變量聲明:<變量名> <類型及長度> [:=<初始值>]
例:v_name varchar2(20):=’張三’;
例:見第3節
2、 循環語句
loop循環語法:
loop
exit when 表達式
end loop;
while循環語法:
while 表達式 loop
end loop;
for循環語法:
for <變量> in <變量取值范圍(小值..大值,如1..100)> loop
end loop;
for循環的變量可不做聲明及初始化。
例:見第3節
3、 if判斷語句
基本語法:
if <表達式> then
…
else if <表達式> then
…
else
…
end if;
end if;
例:
declare
v_identity number(4):=0;
begin
loop
if v_identity=1 then
dbms_output.put_line('v_identity=1');
else if v_identity=3 then
dbms_output.put_line('v_identity=3');
else if v_identity=6 then
exit;
else
dbms_output.put_line('v_identity is not 1 or 3');
end if;
end if;
end if; -- 注意,有多少個if就要有多少個end if結束標志。
v_identity:=v_identity+1;
end loop;
exception
when others then dbms_output.put_line('error!');
end;
/
4、 分支case
基本語法:
case <變量>
when 常量 then
…
when 常量 then
…
else
…
end case;
例:
declare
v_number number(4):=3;
v_string varchar(20):='abc';
begin
case v_number
when 1 then
dbms_output.put_line('v_number is '||1);
when 2 then
dbms_output.put_line('v_number is '||2);
when 3 then
dbms_output.put_line('v_number is '||3);
end case;
case v_string
when 'ab' then
dbms_output.put_line('v_string is '||'ab');
when 'bc' then
dbms_output.put_line('v_string is '||'bc');
else -- 缺省匹配
dbms_output.put_line('v_string is other value');
end case;
exception
when others then dbms_output.put_line('error!');
end;
/
5、 異常(exception)
聲明異常語法:<異常名> exception;
拋出異常語法:raise <異常名>;
捕獲異常語法:when <異常名> then 異常處理語句;
例:
declare
v_input varchar2(1):='&throw';-- 動態輸入
v_exception_1 exception; -- 自定義異常
v_exception_2 exception;
others exception; -- 系統異常
begin
if v_input='1' then
raise v_exception_1; -- 拋出異常
else if v_input='2' then
raise v_exception_2;
else
raise others;
end if;
end if;
exception
-- 捕獲異常
when v_exception_1 then dbms_output.put_line('throw exception: v_exception_1');
when v_exception_2 then dbms_output.put_line('throw exception: v_exception_2');
when others then dbms_output.put_line('throw exception: others');
end;
/
6、 游標(cursor)
聲明游標語法:cursor <游標名> is select語句;
聲明ref游標語法:<游標名> is ref cursor;
打開游標語法:open <游標名>;
移動游標並獲取數據語法:fetch <游標名> into <用於保存讀取的數據的變量的名>;
關閉游標語法:close <游標名>;
游標屬性(游標的屬性必須在關閉游標之前):
%isopen: 判斷游標是否打開
%notfound: 找不到數據時
%found:
%rowcount: 返回當前游標已掃描的數據行數量
游標分類:1、顯示游標(自定義游標);2、隱示游標(系統游標);3、REF游標
例:
declare
v_row t_test%rowtype; -- 匹配t_test表中一行所有的數據類型
cursor v_cur is select * from t_test;-- 聲明游標
begin
open v_cur;-- 打開游標
loop
fetch v_cur into v_row;-- 將游標所在行的數據轉存到v_row中
exit when v_cur%notfound; -- 當游標到最后一行時跳出
dbms_output.put_line('id = '||v_row.t_id||' name = '||v_row.t_name||' msg = '||v_row.t_msg);
end loop;
close v_cur;-- 關閉游標
exception
when others then dbms_output.put_line('throw exception: others');
end;
/
-- REF游標 --
create or replace package upk_select_test
as type uc_test is ref cursor; -- 聲明ref游標
end upk_select_test;
/
-- 存儲過程中調用ref游標,並將查詢結果以游標的方式返回
create or replace procedure up_select_test_2
(uc_result out upk_select_test.uc_test)
is
begin
open uc_result for select * from t_test;
end up_select_test_2;
/
7、 通配類型操作符
%type: 通配某行某列數據類型,如v_name t_test.t_name%type;通配表t_test中的t_name。
%rowtype: 通配一行所有列的數據類型,如 v_row t_test%rowtype;匹配t_test表中一行
所有的數據類型。
8、 存儲過程(procedure)
基本語法:
create procedure <過程名>(<參數列表,無參時忽略>)
as|is
變量聲明、初始化
begin
業務處理、邏輯代碼
exception
異常捕獲、容錯處理
end <過程名>;
參數:<參數名> in|out|in out <參數類型,無長度說明> ,如:v_name varchar2
in:入參
out:出參
in out:出入參
注:as|is表示as或is
調用語法:
1)、exec <過程名>;
2)、execute <過程名>;
3)、在PL/SQL語句塊中直接調用。
例:
create or replace procedure up_wap(v_param1 in out varchar2,v_param2 in out varchar2)
is
v_temp varchar2(20);
begin
dbms_output.put_line('交換前參數1:'||v_param1||' 參數2:'||v_param2);
v_temp:=v_param1;
v_param1:=v_param2;
v_param2:=v_temp;
dbms_output.put_line('交換后參數1:'||v_param1||' 參數2:'||v_param2);
exception
when others then dbms_output.put_line('There is a error when the procedure up_wap executing!');
end up_wap;
/
-- 調用存儲過程
declare
v_param1 varchar2(20):='param1';
v_param2 varchar2(20):='param2';
begin
up_wap(v_param1 => v_param1,v_param2 => v_param2);
end;
/
9、 自定義函數(function)
基本語法:
create function <函數名>(<參數列表,無參時忽略>)
return <返回值類型,無長度說明>
as|is
變量聲明、初始化
begin
業務處理、邏輯代碼
return <返回的值>;
exception
異常捕獲、容錯處理
end <函數名>;
參數:in 入參
注:只有入參的類型。
在存儲過程和自定義函數中的參數的傳遞(入參和出參)不能使用%type或%rowtype匹配,不能使用空值null,但是存儲過程可以返回空值。
例:
create function uf_select_name_by_id_test(v_id in number)
return varchar2
is
v_name t_test.t_name%type;
begin
select t_name into v_name from t_test where t_id=v_id;
return v_name;
exception
when others then dbms_output.put_line('error');
end uf_select_name_by_id_test;
/
select uf_select_name_by_id_test(1) 姓名 from dual;-- select調用
declare --pl/sql語句塊調用
v_name varchar2(20);
begin
v_name:=uf_select_name_by_id_test(1);
dbms_output.put_line('name = '||v_name);
end;
/
10、包(package)
封裝,可以封裝過程(procedure)、函數(function)和變量。
注意,在包(package)中聲明的過程(procedure)和函數(function)必須在包的實現體
(package body)中定義實現。
基本語法:
create package <包名>
as|is
變量聲明
存儲過程聲明
自定義函數聲明
end <包名>;
/
create package <包名,與聲明部分一致>
as|is
存儲過程的代碼實現
自定義函數的代碼實現
end <包名>;
/
例:
-- 創建包upk_hello
create or replace package upk_hello
is
v_hello_world varchar2(20):='hello world'; -- 聲明變量
procedure up_hello_world(v_name in varchar2);-- 聲明過程
function uf_hello_world(v_name in varchar2) return varchar2;-- 聲明函數
end upk_hello;
/
-- 實現包(upk_hello)里聲明的方法
create or replace package body upk_hello
is
procedure up_hello_world(v_name in varchar2)
is
v_string varchar2(100);
begin
v_string:=v_name||' say hello world!';
dbms_output.put_line(v_string);
exception
when others then dbms_output.put_line('error');
end up_hello_world;
function uf_hello_world(v_name in varchar2) return varchar2
is
v_string varchar2(100);
begin
v_string:=v_name||' say hello world!';
return v_string;
exception
when others then dbms_output.put_line('error');
end uf_hello_world;
end upk_hello;
/
-- 包的調用
declare
v_msg varchar2(100);
begin
upk_hello.up_hello_world('bing');
v_msg:=upk_hello.uf_hello_world('admin');
dbms_output.put_line(v_msg);
dbms_output.put_line(upk_hello.v_hello_world);
end;
/