自己總結的包和過程的筆記

總結建立包的步驟

需要建立兩部分

建立包的說明

createor replace package EMPLOYEE_PKG
as
procedure PRINT_ENAME;
end  EMPLOYEE_PKG;

建立包體

CREATEOR REPLACE PACKAGE BODY employee_pkg as
   Procedure print_ename    is
   Begin

Dbms_output.put_line('ss');
End print_ename;
End employee_pkg;

包的其他例子

CREATEOR REPLACE PACKAGE globalPkg AUTHID CURRENT_USER AS
/* The following are T/SQL specific global variables. */
  identity  INTEGER;
  trancount INTEGER := 0;
  TYPE RCT1 IS REF CURSOR;/*new weakcursor definition*/
  PROCEDURE incTrancount;
  PROCEDURE decTrancount;
END globalPkg;
CREATE OR REPLACE PACKAGE BODY globalPkg AS
/* This is a dummy package body added by the migration
   workbench in order to emulate T/SQLspecific global variables. */
PROCEDURE incTrancount IS
BEGIN
  trancount := trancount + 1;
END incTrancount;
PROCEDURE decTrancount IS
BEGIN
  trancount := trancount - 1;
END decTrancount;
END globalPkg;

(一) 過程的定義:

這些命名的PL/SQL塊成爲存儲過程和函數,他們的集合、稱爲程序包。

存儲過程

 

· 存儲於數據庫中的函數,過程是數據庫對象。叫存儲過程 

· 存儲過程經編譯和優化後存儲在數據庫服務器中,使用時只要調用即可 

我們可以命名我們的PL/SQL塊,併爲他們確定參數,存儲在數據庫中。這樣可以從任何數據庫客戶端或者工具引用和運行他們,比如SQL*PLUS, Pro*C, JDBC

(二) 優點:

1.  可重用性:一旦命名並保存在數據庫中後,任何應用都可以

2.  抽象和數據隱藏..

3.  可保證數據的安全性和完整性。

4.  存儲過程的能力大大增強了SQL語言的功能和靈活

性。存儲過程可以用流控語句編寫,有很強的靈

活性,可以完成複雜的判斷和較複雜的運算。

  

(三) 語法:

CREATE   OR  REPLACE

PROCEDURE  name [ (parameter [,parameter,…] ) ] IS            //AS

   [說明:變量定義於此]

BEGIN

  執行語句序列

[EXCEPTION

   例外處理程序

END [name ];

用戶通過create or repalce語句可以建立存儲於服務器端的存儲過程。存儲過程不能用於sql語句。(Procedures cannot be used in SQLstatements; 

Procedure0或多個參數,參數可是(IN), output (OUT),  (IN OUT)

類型.

執行存儲過程

set serveroutputon

/

直接執行:

execute my_proc

exec my_proc

(四) 權限:

表和視圖具有SELECT, INSERT, UPDATE, DELETE 這樣的特權,而過程具有EXECUTE特權。只有將EXECUTE特權賦予用戶,用戶纔可以運行它。而將它賦予PUBLIC用戶,則所有用戶都可以運行。

其實我們可以將比較複雜的查詢寫成函數.然後到存儲過程中去調用這些函數.

(五) :Oracle中的函數與存儲過程的區別:

A:函數必須有返回值,而過程沒有.

B:函數可以單獨執行.而過程必須通過execute執行.

C:函數可以嵌入到SQL語句中執行.而過程不行.

(六) 過程裏要返回一個結果集,.就必須要用到遊標了!用遊標來處理這個結果集.

create or replaceprocedure Test

(

varEmpNameemp.ename%type

)

is begin ------會報錯.錯誤原因沒有into子句.

select * from empwhere ename like '%'||varEmpName||'%';

end;

這個程序我們無法用into,因爲在Oracle裏面沒有一個類型去接受一個結果集.這個時候我們可以聲明遊標對象去接受他.

L/SQL遊標:

A:分類:

1:隱式遊標:非用戶明確聲明而產生的遊標你根本看不到cursor這個關鍵字.

2:顯示遊標:用戶明確通過cursor關鍵字來聲明的遊標.

B:什麼是隱式遊標:

1:什麼時候產生:

會在執行任何合法的SQL語句(DML---INSERTUPDATE DELETE DQL-----SELECT)中產生.他不一定存放數據.也有可能存放記錄集所影響的行數.

如果執行SELECT語句,這個時候遊標會存放數據.如果執行INSERT UPDATE DELETE會存放記錄影響的行數.

C:隱式遊標叫什麼名字:

名字叫sql

關於sql的遊標變量到底有哪些呢?

作用:返回最近一次執行SQL語句所涉及的遊標相關信息.因爲每執行一次SQL語句,都會產生一個隱式遊標.那麼當前執行的SQL語句就是當前的隱式遊標.

sql%found

sql%notfound

sql%rowcount

sql%isopen

D:關於隱式遊標的例子:

create table 學生基本信息表

(

StuID int,

StuName varchar2(20)

)

alter table 學生基本信息表 addconstraint PK_STUID primary key(StuID)

declare

num int:=0;

begin

num:=#

delete from 學生基本信息表where StuID=num;

if sql%notfound then

dbms_output.put_line('該行數據沒有發現');

else

dbms_output.put_line('數據被發現並刪除,影響的行數爲:'||sql%rowcount);

end if;

end;

E:關於顯示遊標的例子:

1:如何定義顯示遊標

declare cursor <cursor_name> is[select語句];

declare cursor mycur is selectempno,ename,job from scott.emp;

2:如何打開遊標:

open <cursor_name>;

open mycur;

3:如何通過遊標來讀取數據

fetch <cursor_name> into<variable_list>

4:如何關閉遊標:

close <cursor_name>;

close mycur;

注意:在Oracle中,不需要顯示銷燬遊標.因爲在Oracle中,很多東西是由JAVA寫的.Oracle會自動銷燬遊標.

5:舉例:

declare

cursor mycur is select empno,ename,job fromemp;

vempno emp.empno%type;

vename emp.ename%type;

vjob emp.job%type;

begin

open mycur;

fetch mycur into vempno,vename,vjob;

dbms_output.put_line('I FoundYou!'||mycur%rowcount||'行');

dbms_output.put_line('讀取的數據爲'||vempno||' '||vename||' '||vjob);

close mycur;

end;

因爲只讀出來一條,所以要遍歷一下:

declare

cursor mycur is select empno,ename,job fromemp;

vempno emp.empno%type;

vename emp.ename%type;

vjob emp.job%type;

begin

open mycur;

loop

fetch mycur into vempno,vename,vjob;

exit when mycur%notfound;

if mycur%found then

dbms_output.put_line('讀取的數據爲'||vempno||' '||vename||' '||vjob);

end if;

end loop;

dbms_output.put_line('I FoundYou!'||mycur%rowcount||'行');

close mycur;

end;

6:通常情況下我們在讀取表數據的時候,我們需要動態的去查詢.所以能不能在Oracle中給遊標帶參數呢?可以!

1):如何定義帶參數的遊標:

declare cursor <cursor_name>(參數名稱 參數類型描述) is select xxxxx from bbbbb where aaa==???and ccc=???;

2):例子:

遊標是一個集合,讀取數據有兩種方式

第一種方式: open fetch close

第二種方式: for 一但使用了for循環在循環剛剛開始的時候,相當於執行open,在處理循環的時候,相當於執行fetch,

在退出循環的時候,相當於執行了close

declare

cursor query(vnamevarchar) is select empno,ename,job from emp where ename like'%'||vname||'%';

begin

for line inquery('A')

loop

dbms_output.put_line(line.empno||''||line.ename||' '||line.job);

end loop;

end;

實現動態輸入:

declare

cursor query(vnamevarchar) is select empno,ename,job from emp where ename like'%'||vname||'%';

name1 varchar(10);

begin

name1:=upper('&name1');

for line in query(name1)

loop

dbms_output.put_line(line.empno||''||line.ename||' '||line.job);

end loop;

end;

使用REF遊標

       是一種引用類型,類似於指針。

顯式和隱式遊標的區別:

儘量使用隱式遊標,避免編寫附加的遊標控制代碼(聲明,打開,獲取,關閉),也不需要聲明變量來保存從遊標中獲取的數據。

REF CURSOR遊標:

動態遊標,在運行的時候才能確定遊標使用的查詢。分類:

類型(限制)REF CURSOR,規定返回類型

弱類型(非限制)REFCURSOR,不規定返回類型,可以獲取任何結果集。

TYPE ref_cursor_name IS REF CURSOR[RETURN return_type]

使用REF CURSOR遊標:返回結果集合

create or replaceprocedure pro_shuijs(gh in varchar2, RC1   INOUT globalPkg.RCT1) is

begin

OPEN RC1 FOR

select a.zgbhao00 ,a.xming000,GZHJI000+je000000,nvl(SYBXIAN0,0)+nvl(YBAO0000,0)+nvl(YLBXIAN0,0)+nvl(GJJIN000,0) ,
   je000000 補充保險,a.sdshui00 稅金
from rlvgzsjx2 a  ,rltrsdawhxxb,rltdygzlsb c,  rlvwcylgj1 d
where a.zgbhao00=c.zgbhao00(+) and
a.zgbhao00=d.zgbhao00(+) and   a.nyue0000=d.nyue0000(+) and
  a.zgbhao00=b.zgbhao00(+)   and    a.zgbhao00=gh ; 
  end pro_shuijs;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章