1. 程式人生 > >Oracle plsql匿名塊、record、table、type、rowtype、異常種類

Oracle plsql匿名塊、record、table、type、rowtype、異常種類

 

plsql匿名塊、record、table、type、rowtype、異常

 

/**
1.1 pl/sql(資料庫程式設計):是對錶中的sql語句的擴充套件,擴充套件了過程化的控制
1.2 
 變數:
資料型別:varchar2(len),nvarchar2(len),char(len),date,boolean,number(p,s)
運算子:|| and or not != <>
邏輯控制:
迴圈結構:
1.3.pl/sql塊:下面相當於一個方法,沒有名字,因此叫匿名塊。declare(宣告)
declare
     定義變數,v是變數的意思
 begin
    寫sql或者pl/sql語句
 exception
      異常處理   
  end;  
**/
------------------------------------------
declare
   -- v_name varchar(20):='烏龜';--宣告變數,同時賦值(第一種賦值)
     v_name varchar(20);
  begin
    v_name:='烏龜';---賦值(第二種賦值)
    select sname into v_name from student where sno='112';--into的意思是把學生表的sname賦值給v_name(第三中賦值)
    dbms_output.put_line(v_name);---列印變數的值,相當於system.out.println()
   end;
--------------------------------
 ---邏輯控制。if else,輸出大年齡
 declare
     v_age number(5):=22;
     v_age2 number(5):=10000;
  begin  ----- if then endif相當於if語句。v_age>v_age2是判斷條件,dbms_output.put_line('v_age:' ||v_age)是輸出的結果
   if v_age>v_age2 then
     dbms_output.put_line('v_age:' ||v_age);
   else
       dbms_output.put_line('v_age2:' ||v_age2);
   end if;  
   end;
-------------------------------------
---邏輯控制。多重if
 declare
     v_age number(5):=22;
     v_age2 number(5):=10000;
  begin  
   if v_age>v_age2 then
     dbms_output.put_line('v_age=' ||v_age);
   elsif v_age=v_age2  then---elsif在java中相當於else if
     dbms_output.put_line('v_age2=' ||v_age2 ||'v_age:' ||v_age);
   else
     dbms_output.put_line('v_age2=' ||v_age2 );---資料管理系統
   end if;  
   end;
-------------------
---邏輯控制。case等值判斷。(在java中就是switch,等值判斷)
 declare
     v_grade number(1):=8;   
  begin  
   case 
     when v_grade=1 then  dbms_output.put_line('☆');
     when v_grade=2 then  dbms_output.put_line('☆☆');
     when v_grade=3 then  dbms_output.put_line('☆☆☆');
     when v_grade=4 then  dbms_output.put_line('☆☆☆☆');
     else dbms_output.put_line('☆☆☆☆11111111');
     end case;
   end;
-----------  
--邏輯控制。case區間判斷
 declare
     v_grade number(3):=89;   
  begin  
   case 
     when v_grade>=90 then  dbms_output.put_line('A');
     when v_grade>=80 then  dbms_output.put_line('B');
     when v_grade>=60 then  dbms_output.put_line('c');
     when v_grade<60then  dbms_output.put_line('d');
     end case;
   end; 
 --------------------
   ---邏輯控制。case用在select中。好像跟sign()很相似
   select sname,
   case 
     when sage>40 then '中上'
     when sage>30 then '中上'
     when sage>20 then '中上'
     when sage<20 then '中上'
         end case
         from student
 ---==================================================================
 ------第二部分:迴圈控制
 -----迴圈結構 loop
  declare
     v_x number(6):=1;   
  begin  
  loop ---迴圈的意思,loop是個死迴圈
    dbms_output.put_line(v_x);
    if  v_x =100 then
      exit;---強制退出迴圈
      end if ;
    v_x:=v_x+1;---結果緩衝區溢位,因為超過10000個位元組了。因為這是個死迴圈
  end loop;
   end; 
 -------------------
  ---迴圈結構 for 。。in後面是個集合
    declare
     v_x number(6):=1;   
  begin  
   for v_x in 1..100 loop ---loop就相當於左大括號,end loop就相當於右邊大括號
    dbms_output.put_line(v_x);
  
  end loop;
   end; 
  ---------------------
 -- 迴圈結構 while 
    declare
     v_x number(6):=1;   
  begin  
   while v_x<=120 loop
    dbms_output.put_line(v_x);
  v_x:=v_x+1;
  end loop;
   end; 
   
------------------------
------第三部分:oracle 複合資料型別(其實就是java中的引用型別)
---1.record記錄型別
--record:就相當於建立類(更確切的說應該是建立表,因為格式更像是建立表,
--因為他裡面的內容都放在了一對括號裡了,每個欄位後面用逗號,而不是分號,最後一個欄位不用逗號)
    declare
    ---- 1.定義一個複合型別v_r  (type是定義型別,相當於定義類,名字v_r)。完成的就是對類的定義和給類中屬性賦值
    type v_r is record
    (
    v_x varchar(20),---這三行相當於是給類加上屬性,更確切的說就是成員物件(或者說是在建表)
    v_y varchar(20),
    v_z varchar(20)
    );----這個表是個整體,因此結束的時候要分號
    ---2.定義複合型別的變數(相當於java建立物件)
    v_n v_r;
  begin  
    --這個sql塊想要說明的就是v_n.v_x(物件.屬性)的使用
  -- v_n.v_x:='安娜';---相當於在java中的利用物件呼叫屬性
  --v_n.v_z:='令狐沖';
  -- v_n.v_y:=23;
   select sname,saddress,sage into v_n.v_x,v_n.v_y,v_n.v_z from student  where sno='112';---這個sql塊想要說明的就是v_n.v_x(物件.屬性)的使用
   dbms_output.put_line(v_n.v_x);
   dbms_output.put_line(v_n.v_y);
   dbms_output.put_line(v_n.v_z);
   end; 
----用處:定義一個record變數存放第二條記錄, 並輸出結果
--------------------------------------------------------
   
 ----2.table型別(相當於陣列) :總結一下:自己指定陣列名字,陣列型別,索引型別,索引名字,不用給陣列指定大小,因為他自己會增加 。完成的就是對陣列的定義和賦值
  declare
   ---1.宣告table型別,of varchar2(23)是陣列中元素的型別,index by 是索引的型別。v_t是陣列型別.索引不用指定大小,會一直增加。索引的型別自己指定,
   ---(索引型別改成number不行(改成其他的不受限制)。因為number可以出現小數位)
   type v_t is table of varchar2(23) index by varchar2(3);
   ---2.定義v_t型別的變數,現在v_a就是陣列變數
   v_a v_t;
  begin  
   select sname,saddress into v_a('1'),v_a('2')  from student where sno='112';----這裡的1,2代表索引(型別是varchar2(3))。這索引也是自己定義的。但是要注意在select後面的列的型別,要跟陣列的型別一致
dbms_output.put_line(v_a('x'));
   end; 
----用處:定義一個table 型別變數存放3條記錄, 並輸出結果
---====================================================  
---第四部分:擴充套件變數型別
----題:把表中某列的值賦值到一個變數裡,但是我不知道這些列的資料型別
---1.%type  賦值某一列(一個欄位)
declare 
  v_name student.sname%type;----student.sname%type是student表中的sname列的資料型別
  v_age student.sage%type;
  begin
    select sname ,sage into v_name,v_age from student where sno='112';---into是把sname的值給v_name
    dbms_output.put_line(v_name);
    dbms_output.put_line(v_age);
    end;
---2.%rowtype   賦值某一行(也就是所有列)
declare 
  v_x student%rowtype;----student.sname%type將sname變數的資料型別賦值
  begin
    select sname,sage into v_x.sname,v_x.sage from student where sno='112';
    dbms_output.put_line(v_x.sname);
    dbms_output.put_line(v_x.sage);
    end;
------這兩個的用處:用pl/sql實現輸出7369號員工的姓名
--=================================================
-----第五部分:異常
---1.java中用異常類來描述(描述類名和異常的具體產生資訊,異常編號)。
     ---oracle中描述異常:
             ---異常名字
             --異常的具體描述資訊
             --異常編號
---2.oracle中異常的分類,按照異常名稱分類
   ---預定義異常:名稱,描述,編號都由oracle系統提供(相當於java的異常類)
   ---非預定義異常:指提供描述和編號(沒有名字的異常)
   ---自定義異常:三無。名稱,描述和編號都由程式設計師自己提供
--------------------------------------------------
-----預定義異常。異常1
declare
   v_num number(3):=10;
   v_num2 number(3):=0;
   v_num3 number(3);
begin
  v_num3 :=v_num/v_num2; 
exception
    when ZERO_DIVIDE  then---除零異常
      --dbms_output.put_line('這裡有除數為0異常');--這裡漢字就是描述
    dbms_output.put_line(sqlcode||'----'||sqlerrm);--系統編號sqlcode和中文描述sqlerrm
       when others then---所有異常,others相當於exception
      dbms_output.put_line('這裡有異常');
end;
---------------------------
--預定義異常 異常2
declare

       v_name varchar2(20);
begin
       ---select sname into v_name from student where sno='112';--應該這樣寫,但是為了測試異常沒有加where條件
       select sname into v_name from student;
exception 
       when too_many_rows then-----實際返回的行數超出請求的行數,因為sname能查出好多,而v_name只能儲存一個
       dbms_output.put_line(sqlcode||'鄙視你'||sqlerrm);
end; 
-----
--------第二種:非預定義異常
declare
---1.宣告異常名字
   v_bajie exception;----這跟定義變數一樣,變數名字 變數型別
----2.給非預定義異常編號為2291的異常繫結一個名字,名字為v_bajie
--(因為名字都是程式設計師起的,因此在系統中根本不可能給他編號,,因此要程式設計師自己給繫結編號。程式設計師要用20000-20999之間的數)
  pragma exception_init(v_bajie,-2291) ; 
begin
 insert into score values('129','200','3',2);---新增成績的時候要考慮主外來鍵關係,129和200都是外檢,但是在主表中沒有這個資料
  exception
    when v_bajie then
     dbms_output.put_line(sqlcode||' 八戒異常 '||sqlerrm);
end; 

-------
---第三種異常:自定義異常
declare
---假設描述倉庫管理員,當數量小於5的時候產生異常
v_count number(3):=2; ---宣告變數,表示庫存數量
 ---1.宣告名稱
   v_wkex  exception ;
  ---2.將異常名稱和異常編號進行繫結。其中,pragma是編譯指令,在編譯是時候被處理,不在執行的時候執行
  pragma exception_init(v_wkex,-20001);
begin
 
  ---3.產生異常(引發異常,就是丟擲)
  if v_count<5  then
   --  raise v_wkex ;--1.丟擲。這種方式不能進行描述
   raise_application_error(-20001,'異常描述,庫存不足');---2.進行關聯,把名稱和描述關聯。自己描述的
    end if;
  exception
    ---4.使用名稱進行處理
     when v_wkex then
   dbms_output.put_line(sqlcode||'    '||sqlerrm);---此時的編號是自己定義的編號-20001,描述也是自己的描述:異常描述,庫存不足
end;

 

https://1601844782.iteye.com/blog/2267595