1.寫出plsql程序的結(jié)構(gòu) 并說明每一部分的作用
2.寫出 表名.字段名%type 的含義? 以及? 表名%rowtype 的含義
3.把下面的java 代碼 翻譯成 PLSQL的語法
? if(a > b){
? }else if(a > c){
? }else{
? }
4.使用while 循環(huán)? 把一個(gè)變量的值 從 1 輸出到? 10?
5.寫出PLSQL中的游標(biāo)的使用步驟? 并寫出每一步的關(guān)鍵代碼
------------------------------------------------------------------------------
1.定義一個(gè)游標(biāo)? 用來存放 s_emp 表中的? id? first_name? salary.
? 提取這個(gè)游標(biāo)的前兩條數(shù)據(jù)? 并打印。
declare
? ? cursor? empcursor is select? id,first_name name,salary from s_emp;
? ? var_emp? empcursor%rowtype;
begin
? ? open? empcursor;
? ? fetch? empcursor? into? var_emp;
? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? fetch? empcursor? into? var_emp;
? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? close? empcursor;
end;
/
2.如何提取出? 游標(biāo)中所有的數(shù)據(jù)?
? 游標(biāo)屬性?
游標(biāo)名 % found? 當(dāng)提取游標(biāo)數(shù)據(jù)時(shí)? 如果提取到了新數(shù)據(jù) 則這個(gè)屬性返回TRUE。
? ? 如果沒有提取到新數(shù)據(jù)則返回FALSE端仰。注意這個(gè)屬性使用有兩個(gè)前提 第一游標(biāo)
? ? 必須處于打開狀態(tài) 否則就報(bào)非法游標(biāo)的錯(cuò),第二游標(biāo)必須fetch 否則返回NULL。
游標(biāo)名 % notfound? 當(dāng)提取游標(biāo)數(shù)據(jù)時(shí)? 如果提取到了新數(shù)據(jù) 則這個(gè)屬性返回FALSE壶笼。
? ? 如果沒有提取到新數(shù)據(jù)則返回TRUE。注意這個(gè)屬性使用有兩個(gè)前提 第一游標(biāo)
? ? 必須處于打開狀態(tài) 否則就報(bào)非法游標(biāo)的錯(cuò),第二游標(biāo)必須fetch 否則返回NULL融求。?
使用簡單循環(huán) 結(jié)合 notfound 屬性遍歷游標(biāo)? ? ? ? ?
declare
? ? cursor? empcursor is select? id,first_name name,salary from s_emp;
? ? var_emp? empcursor%rowtype;
begin
? ? open? empcursor;
? ? loop
? ? ? ? fetch? empcursor? into? var_emp;
? ? ? ? -- 當(dāng)提取不到新數(shù)據(jù)時(shí) 就結(jié)束循環(huán)
? ? ? ? exit? when? empcursor%notfound;
? ? ? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? end loop;
? ? close? empcursor;
end;
/?
使用while循環(huán) 結(jié)合 found 屬性? 遍歷上面的游標(biāo)
? declare
? ? cursor? empcursor is select? id,first_name name,salary from s_emp;
? ? var_emp? empcursor%rowtype;
begin
? ? open? empcursor;
? ? fetch? empcursor? into? var_emp;
? ? while? empcursor%found loop
? ? ? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? ? ? fetch? empcursor? into? var_emp;
? ? end loop;
? ? close? empcursor;
end;
/?
3. 游標(biāo)的其它屬性 (了解)
? 游標(biāo)名%isopen? 判斷游標(biāo)是否打開? 如果是打開狀態(tài)則返回 TRUE? 否則返回false 磷蛹。
? 注意 打開的游標(biāo)不能再打開? 關(guān)閉的游標(biāo) 不能再關(guān)閉。
游標(biāo)名%rowcount? 游標(biāo)指針偏移量? 記錄提取數(shù)據(jù)的指針偏移了多少
4.for 循環(huán) 遍歷游標(biāo)? ---? 智能循環(huán)
? 自動(dòng)定義變量? 自動(dòng)打開游標(biāo)? ? 自動(dòng)提取數(shù)據(jù)? ? 自動(dòng)關(guān)閉游標(biāo)
declare
? ? cursor? empcursor is select? id,first_name name,salary from s_emp;
begin
? ? for var_emp in empcursor loop
? ? ? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? end loop;
end;
/?
5.帶參游標(biāo)
? 定義游標(biāo)時(shí) 可以給游標(biāo)設(shè)計(jì)參數(shù)? 并且這些參數(shù) 可以在游標(biāo)對(duì)應(yīng)的select語句中使用
通過 我們打開游標(biāo)時(shí) 傳入實(shí)參就可以像正常游標(biāo)一樣去遍歷了抖坪。
plsql 中參數(shù)不能加長度修飾? 但是 可以使用 表名.字段名%type萍鲸。
/*帶參游標(biāo)*/
? declare
? ? cursor? empcursor(var_id? number) is select? id,first_name name,
? ? ? ? salary from s_emp where id>var_id;
? ? var_emp? empcursor%rowtype;? ?
? begin
? ? open? empcursor(10);
? ? fetch? empcursor? into? var_emp;
? ? while? empcursor%found loop
? ? ? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? ? ? fetch? empcursor? into? var_emp;
? ? end loop;
? ? close? empcursor;
? end;
? /?
/*for +帶參游標(biāo)*/
? declare
? ? cursor? empcursor(var_id? number) is select? id,first_name name,
? ? ? ? salary from s_emp where id>var_id;?
? begin
? ? for var_emp in empcursor(15) loop
? ? ? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? end loop;
? end;
? /?
6.參考游標(biāo)? ref cursor
6.1? 動(dòng)態(tài)sql的思路
? 本質(zhì)是游標(biāo)對(duì)應(yīng)的sql語句 是一條字符串
? 語句是字符串? 則 在程序運(yùn)行的過程中 sql語句可以根據(jù)條件發(fā)生改變。
6.2? ref cursor 的使用 步驟
? ? a.定義一個(gè)參考游標(biāo) 游標(biāo)類型
? ? ? ? type? 參考游標(biāo)類型? is? ref cursor;
? ? b.使用這個(gè)類型定義一個(gè)游標(biāo)變量
? ? ? ? ? ? ? ? ? 游標(biāo)變量? 參考游標(biāo)類型;
? ? c.打開游標(biāo)變量? 傳入對(duì)應(yīng)的字符串? ?
? ? ? ? open? 游標(biāo)變量? for? sql字符串;
6.3 案例
/*if 拼接字符串 參考游標(biāo)*/
? ? declare
? ? ? ? type? myrefcursor is? ref cursor;
? ? ? ? empcursor? myrefcursor;
? ? ? ? sqlstr? ? varchar2(200);
? ? ? ? id? ? ? ? s_emp.id%type:=10;
? ? ? ? salary? ? s_emp.salary%type:=2000;
? ? ? ? type? emptype is? record(
? ? ? ? ? ? id? ? s_emp.id%type,
? ? ? ? ? ? name? s_emp.first_name%type,
? ? ? ? ? ? salary s_emp.salary%type
? ? ? ? );
? ? ? ? var_emp? emptype;
? ? begin
? ? ? ? sqlstr:='select id,first_name name,salary from s_emp where 1=1 ';
? ? ? ? if id is not null? then
? ? ? ? ? ? sqlstr:=sqlstr||' and id<' || id;
? ? ? ? end? if;
? ? ? ? if? salary? is? not null then
? ? ? ? ? ? sqlstr:=sqlstr||' and salary < ' || salary;
? ? ? ? end? if;
? ? ? ? dbms_output.put_line(sqlstr);
? ? ? ? -- 打開游標(biāo)變量時(shí) 傳入對(duì)應(yīng)的字符串
? ? ? ? open? empcursor? for? sqlstr;
? ? ? ? loop
? ? ? ? ? ? fetch? empcursor? into? var_emp;
? ? ? ? ? ? exit when? empcursor%notfound;
? ? ? ? ? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? ? ? end loop;
? ? end;
? ? /
? /*占位符參考游標(biāo)*/
? declare
? ? ? ? type? myrefcursor is? ref cursor;
? ? ? ? empcursor? myrefcursor;
? ? ? ? sqlstr? ? varchar2(200);
? ? ? ? id? ? ? ? s_emp.id%type:=10;
? ? ? ? salary? ? s_emp.salary%type:=2000;
? ? ? ? type? emptype is? record(
? ? ? ? ? ? id? ? s_emp.id%type,
? ? ? ? ? ? name? s_emp.first_name%type,
? ? ? ? ? ? salary s_emp.salary%type
? ? ? ? );
? ? ? ? var_emp? emptype;
? ? begin
? ? ? ? sqlstr:='select id,first_name name,salary from s_emp where id < :b0 and salary < :b1';
? ? ? ? /* 當(dāng)出現(xiàn) :開頭的占位符時(shí)? 使用 using? 傳入實(shí)參 */
? ? ? ? open? empcursor? for? sqlstr using id,salary;
? ? ? ? loop
? ? ? ? ? ? fetch? empcursor? into? var_emp;
? ? ? ? ? ? exit when? empcursor%notfound;
? ? ? ? ? ? dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
? ? ? ? end loop;
? ? end;
? ? /
7.異常? (了解)
? 7.1 異常的分類
? ? ? 編譯時(shí)異常? ? 語法錯(cuò)誤
? ? ? 運(yùn)行時(shí)異常? ? 程序運(yùn)行的過程中產(chǎn)生的錯(cuò)誤
? 7.2 舉例
? declare
? ? ? var_name? s_emp.first_name%type;
? begin
? ? ? select? first_name? into var_name? from s_emp? where id=111;
? ? ? dbms_output.put_line(var_name);
? end;
? /
? 一個(gè)程序執(zhí)行? 可能出現(xiàn)異常? 也可能不出現(xiàn)異常
? 7.3 如何處理
? 異常處理 就是提前寫好 程序的問題處理方案?
? declare
? ? ? var_name? s_emp.first_name%type;
? begin
? ? ? select? first_name? into var_name? from s_emp? where id=11;
? ? ? dbms_output.put_line(var_name);
? exception
? ? ? when? NO_DATA_FOUND? then
? ? ? dbms_output.put_line('no emp found');?
? ? ? when? TOO_MANY_ROWS then
? ? ? dbms_output.put_line('select too many emp');
? ? ? when? others? ? then
? ? ? -- sqlcode 的意思是sql的狀態(tài)碼? sqlerrm? 的意思是 sql error? message 簡寫
? ? ? dbms_output.put_line('have exception'||':'||SQLCODE||':'||SQLERRM);?
? end;
? /?
? 8.過程? procedure? 10*10*10
? 8.1 什么是過程
? ? ? 完成特定邏輯的一組代碼的邏輯封裝 柳击。
? 8.2 寫一個(gè)plsql 的功能? 定義兩個(gè)整數(shù)變量? 打印這兩個(gè)變量的最大值
? declare
? ? ? var_x? number:=20;
? ? ? var_y? number:=50;
? begin
? ? ? if var_x < var_y? then
? ? ? ? ? dbms_output.put_line(var_y);
? ? ? else
? ? ? ? ? dbms_output.put_line(var_x);
? ? ? end? if;
? end;
? /
? 這叫匿名塊? 直接可以執(zhí)行? 復(fù)用只能拷貝 這樣后期維護(hù)和管理比較復(fù)雜
? 8.3 把上面的匿名塊 改造成 過程
? create? or? replace? procedure? getmax(var_x? number:=20,var_y number:=50)
? is
? begin
? ? ? if var_x < var_y? then
? ? ? ? ? dbms_output.put_line(var_y);
? ? ? else
? ? ? ? ? dbms_output.put_line(var_x);
? ? ? end? if;
? end;
? /
? create? or replace? procedure 過程名(參數(shù)? 參數(shù)類型:=默認(rèn)值,參數(shù)? 參數(shù)類型:=默認(rèn)值)
? is
? ? ? /* 這就是之前的申明區(qū)*/
? begin
? end;
? /
? 8.4 如何調(diào)用
? call? 過程名(參數(shù));
? execute? 過程名(參數(shù));?
? ? ? 這兩種 了解一下? ? call 調(diào)用無參的也必須加()? execute 調(diào)用無參可以不加()
? ? ? 在實(shí)際開發(fā)中 以直接調(diào)用為主
? begin
? ? ? /* 在匿名塊中直接調(diào)用? 匿名塊可以調(diào)用過程? 哪過程也可以調(diào)用過程 */
? ? ? getmax(111,222);
? end;
? /?
? 8.5 寫一個(gè)存儲(chǔ)過程? 設(shè)計(jì)兩個(gè)整數(shù)參數(shù)? 打印這兩個(gè)參數(shù)的最小值? 并使用匿名塊驗(yàn)證功能猿推。
? create? or? replace? procedure? getmin(var_x number:=0,var_y? number:=1)
? is
? begin
? ? ? if var_x < var_y? then
? ? ? ? ? dbms_output.put_line(var_x);
? ? ? else
? ? ? ? ? dbms_output.put_line(var_y);
? ? ? end if;? ?
? end;
? /
? begin
? ? ? getmin();
? ? ? getmin(11,9);
? end;
? /
? 8.6 寫一個(gè)存儲(chǔ)過程? 設(shè)計(jì)三個(gè)整數(shù)參數(shù)? 打印這前兩個(gè)參數(shù)的最小值? 并且把前兩個(gè)參數(shù)的和
? ? ? 存入第三個(gè)參數(shù)中片习。
? static? void? getNum(int x){
? ? ? x=10000;
? }
? int main(){
? ? ? int? x=1;
? ? ? getNum(x);
? ? ? x
? }
? static? void? getString(String? x){
? ? ? x="abc";
? }
? int main(){
? ? ? String? x=new? String("a");
? ? ? getString(x);
? ? ? x
? }
? static? void? getString(StringBuffer? x){
? ? ? x.append("abc");
? }
? int main(){
? ? ? StringBuffer? x = new? StringBuffer("a");
? ? ? getString(x);
? ? ? x
? }
? plsql中默認(rèn)的參數(shù) 是in 參數(shù)? 只能讀不能寫
? ? ? 如果希望存儲(chǔ)過程帶回值? 則使用out 參數(shù)
? create? or? replace? procedure getmin_and_sum(var_x in number,var_y number,
? var_z out number)
? is
? begin
? ? ? dbms_output.put_line('var_z='||var_z);
? ? ? if var_x < var_y? then
? ? ? ? ? dbms_output.put_line(var_x);
? ? ? else
? ? ? ? ? dbms_output.put_line(var_y);
? ? ? end if;
? ? ? var_z:=var_x+var_y;
? end;
? /
? 注意:調(diào)用 帶有out 參數(shù)的過程時(shí),out模式的參數(shù) 必須是變量
? declare
? ? ? var_z? number:=100;
? begin
? ? ? getmin_and_sum(1,9,var_z);
? ? ? dbms_output.put_line(var_z);
? end;
? /
? 參數(shù)的模式:
? ? in? 默認(rèn)的? 只負(fù)責(zé)給存儲(chǔ)過程傳入值
? ? out? 只負(fù)責(zé)給存儲(chǔ)過程傳出值
? ? in out? 既能給存儲(chǔ)過程傳入值 又能傳出值
? ? 寫一個(gè)存儲(chǔ)過程? 設(shè)計(jì)二個(gè)整數(shù)參數(shù)? 打印這兩個(gè)參數(shù)的最小值? 并且把前兩個(gè)參數(shù)的和
? ? ? 存入第二個(gè)參數(shù)中捌肴。
? create? or? replace? procedure getmin_and_sum(var_x in number:=1,
? ? ? var_y? in out number)
? is
? begin
? ? ? if var_x < var_y? then
? ? ? ? ? dbms_output.put_line(var_x);
? ? ? else
? ? ? ? ? dbms_output.put_line(var_y);
? ? ? end if;
? ? ? var_y:=var_x+var_y;
? end;
? /? ?
? 8.7 如何調(diào)用一個(gè)大家不熟悉的存儲(chǔ)過程
? 查看存儲(chǔ)過程? desc? 過程名;
? desc? getmin_and_sum;
? a.獲取參數(shù)的名字
? b.參數(shù)的類型
? c.參數(shù)的模式 如果有out 修飾 則必須是變量
? d.參數(shù)是否有默認(rèn)值? ? 要獲取具體的默認(rèn)值? 測試 查看公司文檔? 查看源代碼
? ? select text? from user_source? where name='GETMIN_AND_SUM';
? ? 參數(shù)的位置賦值
? declare
? ? ? var_y? number:=10;
? begin
? ? ? getmin_and_sum(1,var_y);
? ? ? dbms_output.put_line(var_y);
? end;
? /
? 參數(shù)的名字賦值? 可以改變賦值的順序? 參數(shù)名=>參數(shù)的值? (了解)
? declare
? ? ? var_y? number:=9;
? begin
? ? ? getmin_and_sum(var_y=>var_y,var_x=>1);
? ? ? dbms_output.put_line(var_y);
? end;
? /
? 8.8 設(shè)計(jì)一個(gè)存儲(chǔ)過程? 可以傳入一個(gè)參數(shù) n? 這個(gè)參數(shù)代表從1 加到的數(shù)
? 還有一個(gè)參數(shù)可以存儲(chǔ) 前n項(xiàng)的 和。? 調(diào)用這個(gè)存儲(chǔ)過程驗(yàn)證功能藕咏。
如 n = 10? 1+2+3+4+5+6+7+8+9+10=55
create? or? replace? procedure getNumN(n in number,var_sum? out number)
is
begin
? ? var_sum:=0;
? ? for i in 1..n loop
? ? ? ? var_sum:=var_sum+i;
? ? end loop;
end;
/
declare
? ? var_sum? number:=100;
begin
? ? getNumN(100,var_sum);
? ? dbms_output.put_line('var_sum='||var_sum);
end;
/
? declare
? ? var_sum? number:=100;
begin
? ? getNumN(var_sum=>var_sum,n=>100);
? ? dbms_output.put_line('var_sum='||var_sum);
end;
/?
9.函數(shù)
? 9.1 過程和函數(shù)的區(qū)別
? ? ? a.第一關(guān)鍵字不同? 過程是 procedure? 函數(shù)是 function
? ? ? b.函數(shù)有返回值類型 和 返回值? 而過程沒有
? ? ? c.調(diào)用方式不同? 過程可以直接調(diào)用? 函數(shù)必須組成表達(dá)式才能調(diào)用
? 9.2 語法
? ? ? create? or replace? function? 函數(shù)名(參數(shù)名? 參數(shù)類型:=值,參數(shù)名? 參數(shù)類型:=值)
? ? ? return? 返回值類型?
? ? ? is
? ? ? ? ? -- 定義類型? 定義變量
? ? ? begin
? ? ? ? ? if? 條件? then
? ? ? ? ? ? ? return? 值;
? ? ? ? ? end if;? ?
? ? ? end;
? ? ? /
? 9.3 設(shè)計(jì)一個(gè)plsql 函數(shù) 有兩個(gè)整數(shù)參數(shù)? 返回兩個(gè)參數(shù)的最大值
? ? ? drop? procedure? ? getmax;
? ? ? create or replace? function? getmax(var_x? in number,var_y number)
? ? ? ? return? number?
? ? ? ? is
? ? ? ? begin
? ? ? ? ? ? if? var_x < var_y then
? ? ? ? ? ? ? ? return? var_y;
? ? ? ? ? ? end if;
? ? ? ? ? ? ? ? return? var_x;? ? ?
? ? ? ? end;
? ? ? ? /
? ? 這只是 測試
? ? select? getmax(1,100) from dual;? ? ? ?
? 真正的調(diào)用 有匿名塊 或者 有名塊調(diào)用
? begin
? ? ? dbms_output.put_line(getmax(1,999));
? ? ? if getmax(1,999) > 900 then
? ? ? ? ? dbms_output.put_line('ggggg');
? ? ? end if;
? end;
? /
? 9.4 設(shè)計(jì)一個(gè)函數(shù) 有兩個(gè)整數(shù)參數(shù)? 返回參數(shù)的最大值? 并且把兩個(gè)參數(shù)的和存入第二個(gè)參數(shù)中
? 調(diào)用這個(gè)函數(shù) 驗(yàn)證函數(shù)的功能状知。