44,數據庫(06)

/*
達內學習 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;
  

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