Oracle知識(shí)點(diǎn)總結(jié)(四)

序列: ORACLE使用來(lái)模擬ID自動(dòng)增長(zhǎng)的

create sequence seq_test4;
create table test2(
 tid number primary key,
 tname varchar2(10)    
);

insert into test2 values(seq_test4.nextval,'張三');
select * from test2;

游標(biāo)(光標(biāo)): 是用來(lái)操作查詢結(jié)果集,相當(dāng)于是JDBC中ResultSet

   語(yǔ)法: cursor 游標(biāo)名[(參數(shù)名 參數(shù)類型)] is 查詢結(jié)果集
   
   開發(fā)步驟:
       1. 聲明游標(biāo)
       2. 打開游標(biāo)       open 游標(biāo)名
       3. 從游標(biāo)中取數(shù)據(jù)  fetch 游標(biāo)名 into 變量
                     游標(biāo)名%found :找到數(shù)據(jù)
                     游標(biāo)名%notfound : 沒有找到數(shù)據(jù) 
       4. 關(guān)閉游標(biāo)       close 游標(biāo)名
       
  系統(tǒng)引用游標(biāo)
       1. 聲明游標(biāo) : 游標(biāo)名 sys_refcursor
       2. 打開游標(biāo): open 游標(biāo)名 for 結(jié)果集
       3. 從游標(biāo)中取數(shù)據(jù)
       4. 關(guān)閉游標(biāo)
            
 for循環(huán)遍歷游標(biāo):
       不需要聲明額外變量
       不需要打開游標(biāo)
       不需要關(guān)閉游標(biāo)      

--輸出員工表中所有的員工姓名和工資(不帶參數(shù)游標(biāo))
游標(biāo):所有員工
聲明一個(gè)變量,用來(lái)記錄一行數(shù)據(jù) %rowtype

declare
 --游標(biāo)
 cursor vrows is select * from emp;
 --s聲明變量,記錄一行數(shù)據(jù)
 vrow emp%rowtype;
begin
 --1.打開游標(biāo)  
 open vrows;
 --2.從游標(biāo)提取數(shù)據(jù)
 --循環(huán)取數(shù)據(jù)
 loop
   fetch vrows into vrow; 
   exit when vrows%notfound;  
   dbms_output.put_line('姓名:'||vrow.ename ||' 工資: ' || vrow.sal);
 end loop;
 --3.關(guān)閉游標(biāo)
 close vrows;
end;

--輸出指定部門下的員工姓名和工資
/*
游標(biāo): 指定部門的所有員工
聲明一個(gè)變量記錄一行數(shù)據(jù)
*/

declare
 --聲明游標(biāo)
 cursor vrows(dno number) is select * from emp where deptno = dno;
 --聲明變量
 vrow emp%rowtype;
begin
  --1.打開游標(biāo) , 指定10號(hào)部門
  open vrows(10);
  --2. 循環(huán)遍歷,取數(shù)據(jù)
  loop
 fetch vrows into vrow;
 exit when vrows%notfound;    
  dbms_output.put_line('姓名:'||vrow.ename ||' 工資: ' || vrow.sal);
  end loop;
  close vrows;
end;

--系統(tǒng)引用游標(biāo)
--輸出員工表中所有的員工姓名和工資

  declare
  --聲明系統(tǒng)引用游標(biāo)
vrows sys_refcursor;
  --聲明一個(gè)變量
vrow emp%rowtype;
begin
  --1.打開游標(biāo)
  open vrows for select * from emp;
  --2.取數(shù)據(jù)
loop
  fetch vrows into vrow;
  exit when vrows%notfound;
   dbms_output.put_line('姓名:'||vrow.ename ||' 工資: ' || vrow.sal);
  end loop;
  close vrows;
end;

--擴(kuò)展內(nèi)容----使用for循環(huán)遍歷游標(biāo)

declare
  --聲明一個(gè)游標(biāo)
  cursor vrows is select * from emp;
begin
  for vrow in vrows loop
 dbms_output.put_line('姓名:'||vrow.ename ||' 工資: ' || vrow.sal || '工
作:'|| vrow.job);
  end loop;
end;

select * from emp;

--按照員工工作給所有員工漲工資,總裁漲1000,經(jīng)理漲800,其他人漲400
/*
游標(biāo) : 所有員工
聲明一個(gè)記錄一行數(shù)據(jù)
*/

declare
   --聲明游標(biāo)
   cursor vrows is select * from emp;
   --聲明一個(gè)變量
   vrow emp%rowtype; 
begin
  --1.打開游標(biāo)
  open vrows;
  --2.循環(huán)取數(shù)據(jù)
  loop
   --取數(shù)據(jù)
   fetch vrows into vrow;
   --退出條件
   exit when vrows%notfound;  
   --根據(jù)不同的職位,漲工資 總裁漲1000,經(jīng)理漲800,其他人漲400
   if vrow.job = 'PRESIDENT' then
      update emp set sal = sal + 1000 where empno = vrow.empno;
   elsif vrow.job = 'MANAGER' then
      update emp set sal = sal + 800 where empno = vrow.empno;
   else
      update emp set sal = sal + 400 where empno = vrow.empno; 
   end if;       
  end loop;
  --3.關(guān)閉游標(biāo)
  close vrows;
  --4.提交事務(wù)
  commit;
end;

例外:(意外)程序運(yùn)行的過程發(fā)生異常,相當(dāng)于是JAVA中的異常

 declare
   --聲明變量
  begin
   --業(yè)務(wù)邏輯
 exception
   --處理異常
   when 異常1 then
     ...
   when 異常2 then
     ...
   when others then
     ...處理其它異常
 end;

 zero_divide : 除零異常
 value_error : 類型轉(zhuǎn)換異常
 too_many_rows : 查詢出多行記錄,但是賦值給了rowtype記錄一行數(shù)據(jù)變量
 no_data_found : 沒有找到數(shù)據(jù)
   

 自定義異常:
    異常名  exception;
   raise 異常名          

declare
 vi number;
 vrow emp%rowtype;
begin
 --vi := 8/0;  
--vi := 'aaa';
 --select * into vrow from emp;
 select * into vrow from emp where empno=1234567;
exception
when zero_divide then
dbms_output.put_line('發(fā)生了除零異常');
 when value_error then
 dbms_output.put_line('發(fā)生了類型轉(zhuǎn)換異常');
when too_many_rows then
dbms_output.put_line(' 查詢出多行記錄,但是賦值給了rowtype記錄一行數(shù)據(jù)變量');
when no_data_found then
dbms_output.put_line('沒有找到數(shù)據(jù)異常');
when others then
 dbms_output.put_line('發(fā)生了其它異常' || sqlerrm);     
end;  

--查詢指定編號(hào)的員工,如果沒有找到,則拋出自定義的異常
游標(biāo)來(lái)判斷
%found %notfound
聲明一個(gè)游標(biāo)
聲明一個(gè)變量,記錄數(shù)據(jù)
從游標(biāo)中取記錄
如果有,則不管它
如果沒有就拋出自定義的異常

declare
  --聲明游標(biāo)
  cursor vrows is select * from emp where empno=8888;   
--聲明一個(gè)記錄型變量
  vrow emp%rowtype;
  --聲明一個(gè)自定義異常
  no_emp exception;  
begin
  --1.打開游標(biāo)
  open vrows;
  --2.取數(shù)據(jù)
  fetch vrows into vrow;
  --3.判斷游標(biāo)是否有數(shù)據(jù)
  if vrows%notfound then
raise no_emp;
end if;
close vrows;
exception
when no_emp then
dbms_output.put_line('發(fā)生了自定義的異常');
end;

存儲(chǔ)過程: 實(shí)際上是封裝在服務(wù)器上一段PLSQL代碼片斷,已經(jīng)編譯好了的代碼
1.客戶端取調(diào)用存儲(chǔ)過程,執(zhí)行效率就會(huì)非常高效

     語(yǔ)法:
          create [or replace] procedure 存儲(chǔ)過程的名稱(參數(shù)名 in|out 參
數(shù)類型,參數(shù)名 in|out 參數(shù)類型)
          is | as
           --聲明部分
          begin
           --業(yè)務(wù)邏輯 
          end; 

--給指定員工漲薪,并打印漲薪前和漲薪后的工資
參數(shù) : in 員工編號(hào)
參數(shù) : in 漲多少
聲明一個(gè)變量 : 存儲(chǔ)漲工資前的工資
查詢出當(dāng)前是多少
打印漲薪前的工資
更新工資
打印漲薪后的工資

create or replace procedure proc_updatesal(vempno in number,vnum in number)
is
 --聲明變量.記錄當(dāng)前工資
 vsal number;    
begin
  --查詢當(dāng)前的工資
  select sal into vsal from emp where empno = vempno;
  --輸出漲薪前的工資
  dbms_output.put_line('漲薪前:'||vsal);
  --更新工資
  update emp set sal = vsal + vnum where empno = vempno;
  --輸出漲薪后的工資
  dbms_output.put_line('漲薪后:'||(vsal+vnum));
  --提交
  commit;
end;

調(diào)用:
--方式1
call proc_updatesal(7788,10);

--方式2 用的最多的方式
declare

begin
  proc_updatesal(7788,-100);
end;

存儲(chǔ)函數(shù): 實(shí)際上是一段封裝是Oracle服務(wù)器中的一段PLSQL代碼片斷,它是已經(jīng)編譯好了的代碼片段

    語(yǔ)法: 
         create [or replace] function 存儲(chǔ)函數(shù)的名稱(參數(shù)名 in|out 參數(shù)類
型,參數(shù)名 in|out 參數(shù)類型) return 參數(shù)類型
         is | as
         
         begin
           
         end;
    存儲(chǔ)過程和函數(shù)的區(qū)別:
         1.它們本質(zhì)上沒有區(qū)別
         2.函數(shù)存在的意義是給過程調(diào)用   存儲(chǔ)過程里面調(diào)用存儲(chǔ)函數(shù)
         3.函數(shù)可以在sql語(yǔ)句里面直接調(diào)用
         4.存儲(chǔ)過程能實(shí)現(xiàn)的,存儲(chǔ)函數(shù)也能實(shí)現(xiàn),存儲(chǔ)函數(shù)能實(shí)現(xiàn)的,過程也能實(shí)現(xiàn)
         
    默認(rèn)是 in       

--查詢指定員工的年薪
/*
參數(shù) : 員工的編號(hào)
返回 : 年薪
*/

create or replace function func_getsal(vempno number) return number
is
  --聲明變量.保存年薪
  vtotalsal number;     
begin
  select sal*12 + nvl(comm,0) into vtotalsal from emp where empno = vempno;
  return vtotalsal;
end;

--調(diào)用存儲(chǔ)函數(shù)
declare
  vsal number;
begin
  vsal := func_getsal(7788);
  dbms_output.put_line(vsal);
end;

--查詢員工的姓名,和他的年薪
select ename,func_getsal(empno) from emp;

--查詢指定員工的年薪--存儲(chǔ)過程來(lái)實(shí)現(xiàn)
--參數(shù): 員工編號(hào)
--輸出: 年薪

create or replace procedure proc_gettotalsal(vempno in number,vtotalsal out number)
is
   
begin
  select sal*12 + nvl(comm,0) into vtotalsal from emp where empno = vempno;
end;


declare
  vtotal number;
 begin
  proc_gettotalsal(7788,vtotal);
  dbms_output.put_line('年薪:'||vtotal);
 end;

JAVA調(diào)用存儲(chǔ)過程
JDBC的開發(fā)步驟:
1.導(dǎo)入驅(qū)動(dòng)包
2.注冊(cè)驅(qū)動(dòng)
3.獲取連接
4.獲取執(zhí)行SQL的statement
5.封裝參數(shù)
6.執(zhí)行SQL
7.獲取結(jié)果
8.釋放資源

觸發(fā)器: 當(dāng)用戶執(zhí)行了 insert | update | delete 這些操作之后, 可以觸發(fā)一系列其它的動(dòng)作/業(yè)務(wù)邏輯
作用 :
在動(dòng)作執(zhí)行之前或者之后,觸發(fā)業(yè)務(wù)處理邏輯
插入數(shù)據(jù),做一些校驗(yàn)

   語(yǔ)法:
       create [or replace] trigger 觸發(fā)器的名稱
       before | after
       insert | update | delete 
       on 表名
       [for each row]
       declare
       
       begin
         
       end;
       
   觸發(fā)器的分類:
       語(yǔ)句級(jí)觸發(fā)器:   不管影響多少行, 都只會(huì)執(zhí)行一次
       
       行級(jí)觸發(fā)器:     影響多少行,就觸發(fā)多少次
              :old  代表舊的記錄, 更新前的記錄
              :new  代表的是新的記錄

--新員工入職之后,輸出一句話: 歡迎加入新公司

create or replace trigger tri_test1
after
insert
on emp
declare

 begin
  dbms_output.put_line('歡迎加入新公司');
end;

insert into emp(empno,ename) values(9527,'HUAAN');

--數(shù)據(jù)校驗(yàn), 星期六老板不在, 不能辦理新員工入職
--在插入數(shù)據(jù)之前
--判斷當(dāng)前日期是否是周六
--如果是周六,就不能插入

create or replace trigger tri_test2
before
insert 
on emp
declare
 --聲明變量
 vday varchar2(10);
begin
--查詢當(dāng)前
select trim(to_char(sysdate,'day')) into vday from dual;
  --判斷當(dāng)前日期:
  if vday = 'saturday' then
 dbms_output.put_line('老板不在,不能辦理入職');
 --拋出系統(tǒng)異常
 raise_application_error(-20001,'老板不在,不能辦理入職');
  end if;
end;

insert into emp(empno,ename) values(9528,'HUAAN2');

--更新所有的工資 輸出一句話

create or replace trigger tri_test3
after
update
on emp 
for each row
declare

begin
  dbms_output.put_line('更新了數(shù)據(jù)');
end;

update emp set sal = sal+10;

--判斷員工漲工資后的工資一定要大于漲工資前的工資
200 --> 100
觸發(fā)器 : before
舊的工資
新的工資
如果舊的工資大于新的工資 , 拋出異常,不讓它執(zhí)行成功

觸發(fā)器中不能提交事務(wù),也不能回滾事務(wù)

create or replace trigger tri_updatesal
before
update
on emp
for each row
declare

begin
  if :old.sal > :new.sal then
    raise_application_error(-20002,'舊的工資不能大于新的工資');
  end if;
end;

update emp set sal = sal + 10;
select * from emp;

update emp set sal = sal - 100;

模擬mysql中ID的自增屬性 auto_increment
insert into person(null,'張三');

觸發(fā)器:

pid=1 insert pid=1

序列 : create sequence seq_person_pid;

create table person(
    pid number primary key,
    pname varchar2(20)   
);

insert into person values(null,'張三'); 

create sequence seq_person_pid;

--觸發(fā)器
create or replace trigger tri_add_person_pid
before
insert
on person
for each row
declare

begin
  dbms_output.put_line(:new.pname);
  --給新記錄 pid 賦值
  select seq_person_pid.nextval into :new.pid from dual;
end;

insert into person values(null,'張三'); 

select * from person;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容