總結創建包的步驟sql
須要創建兩部分數據庫
創建包的說明安全
createor replace package EMPLOYEE_PKG
as
procedure PRINT_ENAME;
end EMPLOYEE_PKG;服務器
創建包體ide
CREATEOR REPLACE PACKAGE BODY employee_pkg as
Procedure print_ename is
Begin函數
Dbms_output.put_line('ss');
End print_ename;
End employee_pkg;工具
包的其餘例子oop
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;fetch
(一) 過程的定義:優化
這些命名的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; )
Procedure有0或多個參數,參數但是(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;