/*
達內學習 Oracle day42 2013-10-31
*/
多重循環的退出
declare
var_m number;
var_n number;
begin
while var_m < 4 loop
end loop;
end;
begin
for var_m in 1..3 loop
for var_n in 1..3 loop
dbms__output.put_line(var_n);
if var_n =2 then
goto endouter;
end if;
end loop;
end loop;
<<endouter>>
NULL;
end;
1,在內層循環中修改外層循環條件
2,標籤 goto
-------------------------------------------------------------
SQL 在plsql中的分類
1,select 語句在plsql語句中使用時 要和 into 結合變量使用
select first_name into var_name from s_emp where id = var_id;
2,insert delete update DML
commit rollback savepoint TCL
這寫語句可以直接在plsql中使用
declare
var_id number :=1;
var_name varchar2(30):='test';
begin
insert into testplsql values(2,'app');
commit;
end;
3,DDL
create table drop table alter table
這些語句不能直接在Plsql中使用,需要動態sql
把sql語句變成字符串
動態sql:把一個字符串對應的sql語句,當成真正的sql來執行。
declare
sqlstr varchar2(100);
begin
sqlstr:='create table testplsql(id) number)';
sqlstr:=substr(sqlstr,1,length(sqlstr)-1);
sqlstr:=sqlstr||','||'name varchar2(20)';
/*把字符串 對應 sql當真正sql來執行*/
execute immediate sqlstr;
end;
4,DML語句的
declare
var_id number:=1;
var_name varchar2(30):='test';
sqlstr varchar2(100);
begin
sqlstr:='insert into testplsql values(2,''app'')';
dbms_output.put_line(sqlstr);
sqlstr:= 'insert into testplsql values('||var_id||','''||var_name||''')';
替代字符串拼接 —— 使用佔位符
sqlstr:='insert into testplsql values(:b0,:b1)';
execute immediate sqlstr using var_id,var_name;
5,select 語句動態sql
只能返回一個結果
declare
var_name s_emp.first_name%type;
sqlstr varchar2(300);
begin
sqlstr='select first_name from s_emp where id =2';
execute immedaite sqlstr into var_name;
end;
6,一次可以放多條數據的數據類型 遊標cursor
cursor 的使用步驟
1,聲明cursor
沒有declare關鍵字 cursor 遊標名 is sql語句;
2, 打開cursor
打開遊標 open 遊標名;
3, 提取數據,處理數據
fetch 遊標名 into 變量名;
4,關閉遊標
close 遊標名;
declare
cursor empcursor is select * from s_emp;
var_emp empcursor%rowtype;
begin
open empcursor;
fetch empcursor into var_emp;
dbms_output.put_line(var_emp.id||' '||var_emp.first_name||' '||var_emp.salary);
fetch empcursor into var_emp;
dbms_output.put_line(var_emp.id||' '||var_emp.first_name||' '||var_emp.salary);
close empcursor;
end;
b,遊標的遍歷
遊標的屬性
found 提取數據時,提取到返回真 ,沒有提取到返回假(遊標必須處於打開),不打開就是非法遊標,打開不fetch使用這個屬性返回 NULL。 遊標名%found
notfound 遊標必須處於打開狀態,打開不fetch 則返回 null,如果提取到新數據 返回假,沒有提取到新數據 就返回真。
isopen 遊標是否打開 ,打開返回真,關閉返回假,打開的不能再打開,關閉的不能再關閉
rowcount 當前遊標的指針位移量
使用loop簡單循環 結合notfound 遍歷遊標
declare
cursor empcursor is select * from s_emp;
var_emp empcursor%rowtype;
begin
open empcursor;
loop
fetch empcursor into var_emp;
exit when empcursor%notfound;
dbms_output.put_line(var_emp.id||' '||var_emp.first_name||' '||var_emp.salary);
end loop;
close empcursor;
end;
-----------------------使用while found
declare
cursor empcursor is select * from s_emp;
var_emp empcursor%rowtype;
begin
open empcursor;
while empcursor%found loop
dbms_output.put_line(var_emp.id||' '||var_emp.first_name||' '||var_emp.salary);
fetch empcursor into var_emp;
end loop;
close empcursor;
end;
智能循環(for循環)
declare
cursor empcursor is select * from s_emp;
begin
for var_emp in empcursor loop --不用定義變量,不用 open fetch close
dbms_output.put_line (var_emp.id||':'||var_emp.salary);
end loop;
end;
c,帶參遊標
plsql中的參數不能有任何長度修飾
但是可以使用 %type
但參遊標 只要打開遊標時 傳入實參即可
declare
cursor empcursor(var_id number) is select * from s_emp where id>var_id;
var_emp empcursor%rowtype;
begin
open empcursor(10); --傳參
loop
fetch empcursor into var_emp;
exit when empcursor%notfound;
dbms_output.put_line(var_emp.id||' '||var_emp.first_name||' '||var_emp.salary);
end loop;
close empcursor;
end;
----
for 循環寫法
declare
cursor empcursor(var_id number) is select * from s_emp where id>var_id;
begin
for var_emp in empcursor(10) loop --傳參 不用定義變量,不用 open fetch close
dbms_output.put_line (var_emp.id||':'||var_emp.salary);
end loop;
end;
d,參考遊標
把一個遊標對應的sql語句關聯到一個sql字符串上, 動態sql 和遊標 的結合
declare
type myrefcursor is ref cursor;
/*使用 參考遊標類型 定義遊標變量*/
empcursor myrefcursor;
sqlstr varchar2(100):='select * from s_emp where id >:b0';
var_emp s_emp%rowtype;
var_id s_emp.id%type:=15;
begin
/*打開遊標關聯到字符串*/
open empcursor for sqlstr using var_id;
/* 後邊和正常的遊標一樣*/
loop
fetch empcursor into var_emp;
exit when empcursor%notfound;
dbms_output.put_line(var_emp.salary);
end loop;
end;
-------------------------------------------------------------------------
存儲過程 和 函數
1,存儲過程 procedure
給我們的匿名塊 起名子 存儲到數據庫中
設計兩個整數參數 打印其中最大值
create or replace procedure getmax (x number,y number)
is
var_x number;
var_y number;
begin
var_x:=x;
var_y:=y;
if var_x<var_y then
dbms_output.put_line(var_x);
else
dbms_output.put_line(var_y);
end if;
end;
出現重名函數 drop function getmax
2,察看存儲過程參數 desc getmax
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
X NUMBER IN
Y NUMBER
參數的模式: in(傳入) out(傳出) in out(傳入又傳出)
default: 參數的默認值
3.調用存儲過程
exec getmax(100,200);
call getmax(1,201);
匿名塊調用 或者 有名塊調用
declare
a number :1;
b number :99;
begin
/*參數的位置賦值*/
call getmax(a,b);
-- call getmax(x=>a,y=>b); 參數的名字賦值
end
設計一個存儲過程 把兩個整數參數和放入第三個參數中
create or replace procedure getmax (x in number,y in number,z out number)
is
begin
z:=x+y;
end;
調用:
declare
var_z number:=0;
begin
getmax(1,1,var_z);
end;
----------------------
設計一個存儲過程 傳入兩個整數參數
要求輸出兩個整數參數最大值 還要求把兩個參數的和放入第二個參數中
察看存儲過程 並調用
create or replace procedure mypro(x in number,y in out number,z out number)
is
begin
if x<y then
z:=y;
else
z:=x;
end if;
y:=x+y;
end;
declare
a number:=0;
b number:=4;
c number:=0;
begin
mypro(2,b,c);
dbms_output.put_line(b||' '||c);
end;
察看存儲過程的源代碼
desc user_source;
select text from user_source where name ='MYPRO';
------------------------------------------------------------------
函數
函數和存儲過程的區別
1,關鍵字不同 procedure function
2,過程沒有返回值和返回值類型,函數可以有返回值和返回值類型
return
3,存儲過程可以直接在匿名塊或有名塊裏調用,函數必須組成表達式或者在sql語句中使用。
設計一個函數,傳入兩個整數參數 返回兩個參數的最大值
create or replace function wfungetmax(x in number,y in number) return number
is
begin
if x<y then
return y;
end if;
return x;
end;
察看函數 desc fungetmax
---------------------------------------------------------------
設計一個函數,傳入兩個整數參數,要求返回兩個整數參數的最大值,並且要求把兩個參數的和放入第二個參數中。
察看函數 調用函數
create or replace function fungetmaxsum(x in number,y in out number) return number
is
begin
if x>y then
y:=x+y;
return x;
end if;
x:=x+y;
y:=x-y;
x:=x-y;
y:=x+y;
return x;
end;
-----------------------------------------
create or replace function fungetmaxsum(x in number,y in out number) return number
is
var_temp number; --這裏可以設臨時變量
begin
var_temp:=y;
y:=x+y;
if x<var_temp then
return var_temp;
end if;
return x;
end;
---------------------------------------------------------
參數的默認值
create or replace function testpardef(x number, y number:=123) return number -- 默認值必須靠右,參數有默認值他右側必須也有默認值
is
begin
if x<y then
return y;
else
return x;
end if;
end;
測試:
select testpatdef() from dual; --123
select testpatdef(46545) from dual; --46545
select testpatdef(11,12) from dual; --12
---------------
1,建立存儲過程的語法
create or replace procedure 過程名 (參數名 參數模式 參數類型)
is
臨時變量
begin
end;
2,察看存儲過程
desc 過程名
參數名 類型 參數模式(in out in out) 參數默認值
3,調用存儲過程
sqlplus call exec
匿名塊 有名塊 調用
declare
/*變量定義*/
begin
/*過程調用*/
end;
4,刪除存儲過程
drop procedure 過程名;
5,函數和存儲過程的區別
1,關鍵字
procedure function
2,過程沒有返回值,函數有返回值和返回值類型 return
3,調用方式不同,過程可以直接調用,函數必須組成表達式
4,參數的默認值
----------------------------------------------------
包:package
系統提供的包
dbms_output 系統輸入輸出包
dbms_random 隨機數包
desc ddbms_random;
select trunc(dbms_random.value(1,100)) from dual;
dbms_job 定時任務調度包
定時調用存儲過程
submit(job binary_integer,what varchar2,next_date date,interval varchar2)
會把定時任務提交給系統,系統會爲這個人物分配一個編號 放入job中
next_date 第一次調用的時間
interval 下一次調用的時間
run(job binary_integer); 運行定時任務
remove(job binary_integer); 刪除定時任務
1,建立一張表
create table testjob(
id number primary key,
name varchar2(30),
);
2,建立一個序列
create sequence testjob_id;
3, 寫一個存儲過程 向表添加一條數據
create or replace procedure insert_job
is
begin
insert into testjob values(testjob_id.nextval,'test'||testjob_id.currval);
commit;
end;
4,把存儲過程的調用 交給 dbms_job
declare
jobno binary_integer;
begin
dbms_job.submit(jobno,'insert_job();',sysdate,'sysdate+1/24/60');
dbms_output.put_line('jobbo='||jobno);
dbms_job.run(jobno);
end;
5,刪除
begin
dbms_job.remove(jobno );
end;
----------------------------
自定義包 package
把一組相關的函數 變量 過程等彷彿一個邏輯結構中
相當於頭文件
create or replace package mypack
is
procedure getmax(x number,y number);
function getmin(x number,y number) return number;
end;
包體:相當與C中的實現文件
create or replace package body mypack
is
procedure getmax(x number,y number)
is
begin
if x<y then
dbms_output.put_line(y);
else
dbms_output.put_line(x);
end if;
end;
function getmin(x number,y number) return number
is
begin
if x<y then
dbms_output.put_line(x);
else
dbms_output.put_line(y);
end if;
end;
/*如何調用 數據前加包名*/
begin
mypack.getmin(1,2) from ;
end;