一文總結(jié)總結(jié)存儲過程

PL/SQL(Procedure Language/SQL)

Oracle 對 sql 語言的過程化擴展,指在 SQL 命令語言中增加了過程處理語句(如分支、循環(huán)等),使 SQL 語言具有過程處理能力。

--變量賦值

  • 變量名 類型(長度);
  • 變量名:=變量值
declare
  v1 number(10,2);
 v2 number;
 v3 number(10,2);
 v4 number(10,2);
begin
   v1:=2.45;--單價賦值
  v2:=9213;--水費字?jǐn)?shù)
  v3:=round( v2/1000,2);--噸數(shù)
  v4:=v1*v3;--金額
  DBMS_output.put_line('用水量'||v1);
  DBMS_OUTPUT.put_line('金額:'||v4);
end;
```sql
####   --select  列名 into 變量名
- select 列名 into 變量名 from 表名 where 條件
``` sql
declare
 v1 number(10,2);
 v2 number;
 v3 number(10,2);
 v4 number(10,2);
 vp number;
 vc number;
begin
   v1:=2.45;--單價賦值
  select  t.usenum,t.num0,t.num1 into v2,vp,vc 
  from t_account t 
  where year='2012' and month='01' and t.owneruuid=1;
  v3:=round( v2/1000,2);--噸數(shù)
  v4:=v1*v3;--金額
  DBMS_output.put_line('用水量'||v2);
  DBMS_OUTPUT.put_line('金額:'||v4);
  DBMS_OUTPUT.put_line('上月表數(shù):'||vp);
  DBMS_OUTPUT.put_line('本月表數(shù):'||vc);
 end;

--屬性類型 (引用型 表名.列名%type 表名%rowtype)

 declare
  v_price number(10,2);--單價
  v_usenum2 t_account.usenum%type;--噸數(shù)
  v_money number(10,2);--金額
  v_account t_account%rowtype;--臺賬行記錄類型 
begin
  v_price:=2.45;--單價賦值
  --從數(shù)據(jù)庫中提取一行數(shù)據(jù)賦值給v_account
  select * into v_account from t_account 
  where year='2012' and month='01' and owneruuid=1;
  v_usenum2:=round( v_account.usenum/1000,2);--噸數(shù)
  v_money:=v_price*v_usenum2;--金額
  DBMS_OUTPUT.put_line('字?jǐn)?shù):'||v_account.usenum||'金額:'||v_money);
end;

--異常處理exception

declare
  v_price number(10,2);--單價
  v_usenum2 number(10,2);--噸數(shù)
  v_money number(10,2);--金額
  v_account t_account%rowtype;--臺賬行記錄類型 
begin
  v_price:=2.45;--單價賦值
  --從數(shù)據(jù)庫中提取
  select * into v_account from t_account 
  where year='2012' and month='01' ;
  v_usenum2:=round( v_account.usenum/1000,2);--噸數(shù)
  v_money:=v_price*v_usenum2;--金額
  DBMS_OUTPUT.put_line('字?jǐn)?shù):'||v_account.usenum||'金額:'||v_money);
exception
  when no_data_found  then
    DBMS_OUTPUT.put_line('沒有找到賬務(wù)數(shù)據(jù)');
  when too_many_rows then
    DBMS_OUTPUT.put_line('返回多行賬務(wù)數(shù)據(jù)');
end;

-- 條件判斷(主要中間分支是elsif不是else if)

-- 階梯水價
declare
 p1 number(10,2);
 p2 number(10,2);
 p3 number(10,2);
 v_acc T_ACCOUNT%ROWTYPE;
 v_u2 number(10,2);
 v_m  number(10,2);
begin
  p1:=2.45;
  p2:=3.45;
  p3:=4.45;

  select * into v_acc from t_Account where year='2012' and month='01' and owneruuid=1;
  
  v_u2:=round(v_acc.usenum/1000,2);
  if v_u2<=5 then
    v_m:=v_u2*p1;
  elsif v_u2>5 and v_u2<=10  then
    v_m:=p1*5+(v_u2-5)*p2;
  else
    v_m:=p1*5+p2*5+(v_u2-10)*p3;
  end if;
  DBMS_OUTPUT.put_line('噸數(shù):'||v_u2||'金額:'||v_m||'上月字?jǐn)?shù): '||v_acc.num0||'本月字?jǐn)?shù)'||v_acc.num1);
end;

-- 循環(huán)

--loop
declare
  p1 number:=1;
begin
  loop
    dbms_output.put_line(p1);
    p1:=p1+1;
    exit when p1>100;
  end loop;
end;
--while
declare
  p1 number:=1;
begin
  while p1<=100
  loop
    dbms_output.put_line(p1);
    p1:=p1+1;
  end loop;
end;
---for
begin
  for p1 in 1..100
  loop
    dbms_output.put_line(p1);
  end loop;
end;

--游標(biāo) 數(shù)據(jù)緩沖區(qū),存放 SQL 語句的執(zhí)行結(jié)果

定義:cursor 游標(biāo)名稱 is SQL 語句;
使用:
open 游標(biāo)名稱
loop
fetch 游標(biāo)名稱 into 變量
exit when 游標(biāo)名稱%notfound
end loop;
close 游標(biāo)名稱

--一般提取
declare
  v_p t_Pricetable%rowtype;
  --定義游標(biāo)
  cursor cur_p(v_o_typeid number) is 
  select * from t_Pricetable t where t.ownertypeid=v_o_typeid;
begin
  --打開游標(biāo)
  open cur_p(2);
  --循環(huán)提取游標(biāo)到變量
  loop
    fetch cur_p into v_p;
    exit when cur_p%notfound;
  dbms_output.put_line('價格:'||v_p.price ||'噸位:'||v_p.minnum||'-'||v_p.maxnum );
  end loop;
  close cur_p;
end;

--fro循環(huán)提取 無需打開游標(biāo) 關(guān)閉游標(biāo) 循環(huán)游標(biāo) 提取游標(biāo)
declare
  --定義游標(biāo)
  cursor cur_p(v_o_typeid number) is 
  select * from t_Pricetable t where t.ownertypeid=v_o_typeid;
begin
  --循環(huán)提取游標(biāo)到變量
  for v_p in cur_p(2)
  loop
    dbms_output.put_line('價格:'||v_p.price ||'噸位:'||v_p.minnum||'-'||v_p.maxnum );
  end loop;
end;

存儲函數(shù)

語法結(jié)構(gòu):

CREATE [ OR REPLACE ] FUNCTION 函數(shù)名稱
(參數(shù)名稱 參數(shù)類型, 參數(shù)名稱 參數(shù)類型, ...)
RETURN 結(jié)果變量數(shù)據(jù)類型
IS
 變量聲明部分;
BEGIN
 邏輯部分;
 RETURN 結(jié)果變量;
[EXCEPTION 
 異常處理部分]
END;
-- 根據(jù)地址 ID 查詢地址名稱
create or replace function fn_getadd(v_id number)
return varchar2
is
 v_name varchar2(30);
begin
  select name into v_name from t_address where id=v_id;
  return v_name;
end;

--查詢業(yè)主 ID,業(yè)主名稱,業(yè)主地址,業(yè)主地址使用剛才我們創(chuàng)建的函數(shù)
select id 編號,name 業(yè)主名稱,fn_getadd(addressid) 地址 
from t_owners;

存儲過程

被命名的 PL/SQL 塊,存儲于數(shù)據(jù)庫中,可以調(diào)用存儲過程,執(zhí)行相應(yīng)的邏輯

區(qū)別:

  • 存儲函數(shù)中有返回值,且必須返回;而存儲過程沒有返回值,可以通過
    傳出參數(shù)返回多個值。
  • 存儲函數(shù)可以在 select 語句中直接使用,而存儲過程不能。過程多數(shù)是
    被應(yīng)用程序所調(diào)用。
  • 存儲函數(shù)一般都是封裝一個查詢結(jié)果,而存儲過程一般都封裝一段事務(wù)
    代碼.
    語法
CREATE [ OR REPLACE ] PROCEDURE 存儲過程名稱
(參數(shù)名 類型, 參數(shù)名 類型, 參數(shù)名 類型)
IS|AS
 變量聲明部分;
BEGIN
 邏輯部分
[EXCEPTION 
 異常處理部分]
END;
--增加業(yè)主信息的存儲過程
create or replace procedure p_owners_add(
 v_name varchar2,
 v_addressid number,
 v_housenumber varchar2, 
 v_watermeter varchar2,
 v_type number
) is 
begin
  insert into T_OWNERS 
  values( seq_owners.nextval,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_type );
  commit;
end;
--調(diào)用
call p_owners_add('趙偉',1,'999-3','132-7',1);
select * from T_OWNERS;
  • 帶傳出參數(shù)的存儲過程
--添加業(yè)主信息,傳出參數(shù)為新增業(yè)主的 ID
create or replace procedure p_owners_add(
 v_name varchar2,
 v_addressid number,
 v_housenumber varchar2, 
 v_watermeter varchar2,
 v_type number,
 v_id out number
) is 
begin
  select seq_owners.nextval into v_id from dual;
  insert into T_OWNERS 
  values( seq_owners.nextval,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_type );
  commit;
end;

--調(diào)用
declare
  v_id number;
begin
  p_owners_add('張偉',1,'9-3','132-8',1,v_id);
  dbms_output.put_line('增加成功,ID:'||v_id);
end;

存儲過程綜合案例:

--增加業(yè)主信息時,同時在賬務(wù)表(account)增加一條記錄,
--年份與月份為當(dāng)前日期的年月,初始值(num0)為 0,其它字段信息(區(qū)域)與 t_owners表一致
create or replace procedure p_owners_account_add(
 v_name varchar2,
 v_addressid number,
 v_housenumber varchar2,
 v_watermeter varchar2,
 v_type number,
 v_uid out number
) is
 v_year char(4);
 v_mount char(2);
 v_area number;
begin
  select seq_owners.nextval into v_uid from dual;
  v_year:=to_char(sysdate,'yyyy');
  v_mount:=to_char(sysdate,'mm');
  select areaid into v_area from t_address where id=v_addressid;
  --增加業(yè)主
  insert into T_OWNERS
  values( seq_owners.nextval,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_type );
  --增加賬務(wù)
  insert into t_account(id,owneruuid,ownertype,areaid,year,month,num0)
  values
  (seq_account.nextval,v_uid,v_type,v_area,v_year,v_mount,0);
  commit;
  exception
    when NO_DATA_FOUND then
      v_uid:=-1;
      rollback;
end;
--調(diào)用
declare
  v_id number;
begin
  p_owners_account_add('張偉',1,'9-3','132-8',1,v_id);
  dbms_output.put_line('增加成功,ID:'||v_id);
end;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容