oracle pl/sql 編程基礎

PL/SQL是oracle的專用語言,它對標準的SQL語言的擴展.SQL語句可以嵌套在PL/SQL語言中,並結合處理語句。

PL/SQL程序結構
使用了程序塊的結構組織的代碼.最簡單的程序塊是一種被稱爲”匿名塊”的程序塊,匿名塊是指不會被oracle存儲並且不能夠重用程序塊。
PL/SQL程序通常包括3部分:Declare部分、exception部分、Begin和end部分.
Begin和end是PL/SQL的必須部分,總是begin開始end結束。

Declare部分包含定義變量、常量和遊標等類型的代碼.

Begin與end之間可以嵌套begin與end及exception.

//打開服務器的輸出  
SQL> set serveroutput on;  
SQL> begin //開始  
       dbms_output.put_line('Hello World');  
     end;  
/  

1、變量與常量
變量與常量的聲明:
變量名 類型(字符,日期,數字,布爾)[:=缺省值];
常量名 constant 類型(字符,日期,數字,布爾) [:=缺省值];

變量與常量的區別:
變量可以在任何部分進行賦值.
而常量在declare中聲明並且賦值.

正確的操作:

declare  
    pagesize constant number(2) :=10;  
begin  
    dbms_output.put_line(pagesize);  
end;  
/ 

作用域:
是能夠引用變量名稱這樣的標識符的程序塊。

declare  
   pagesize number(2):=10; //在整個中都有效  
begin  
   dbms_output.put_line(pagesize);  
   declare  
   pagesize number(2):=99; //只是在內容聲明部分到end結束有效  
    begin  
    dbms_output.put_line(pagesize);  
    end;  
end;  
/  

//聲明一個整型的變量

SQL> declare  
        age number(2);  
     begin  
        age:=90;  
        dbms_output.put_line(age);  
     end;  
/ 

//聲明後直接賦值

SQL> declare  
        age number(2) :=90;  
     begin  
        dbms_output.put_line(age);  
     end;  
/ 

//捕獲異常處理

SQL> declare  
        age number(2);  
     begin  
        age :='qwe';  
     exception  
        when others then  
        dbms_output.put_line('賦值失敗');  
     end;  
/ 

2、條件判斷語句
有if與case語句

If語句
If語法

   If(expression1)then pl/sql_statement  
   Else  
        Pl/sql_statement;  
   End if;  
   If(expression1)then pl/sql_statement  
   Else if(expression2)  
        Pl/sql_statement;  
   Else  
        Pl/sql_statement;  
   End if;  

Case語句
從oracle9i以後引入

     Case <selector>  
        When <expression1> then pl/sql_statement1;  
        When <expression2> then pl/sql_statement2;  
        …….  
        [else pl/sql_statement;]  
     End; 

//案例

SQL> declare score number(2) :=80;   
     begin   
          if score>70 then dbms_output.put_line('成績合格');  
     end if;   
     end;  
/  
SQL> declare score number(2) :=80;   
     begin if score>90 then dbms_output.put_line('成績合格');  
     else dbms_output.put_line('成績不合格');   
     end if;   
     end;  
/ 
SQL> declare score number(2):=8;   
     begin   
          case score   
          when 9 then dbms_output.put_line('成績優秀');   
          when 8 then dbms_output.put_line('成績亮');  
     end case;  
     end;  
/  

3、循環語句
最基本的循環稱爲無條件循環,如果沒有指定exit語句,循環將無條件執行,這種循環稱爲死循環,死循環儘量避免。

語法格式如下:

 Loop  
       ---statement---  
 Exit when condition  
 End loop; 

案例:

SQL> declare   
        i number(2):=1;     
     begin   
        loop   
            dbms_output.put_line(i);  
            i:=i+1;   
        exit when i>10;   
     end loop;   
     end;  
/  

While循環
語法:

While condition  
     Loop  
         Statement;  
End loop; 

案例:

SQL> declare   
     i number(2):=1;   
     begin   
         while i<10     
            loop dbms_output.put_line(i);   
                i:=i+1;   
         end loop;   
     end;  
 /  

For循環
語法:

  For loop_control_variable in [reverse] lower upper loop  
         Statement;  
  End loop;  

案例:

SQL> begin  
         for i in 1..10   
            loop   
            dbms_output.put_line(i);   
          end loop;  
     end;  
     / 

PL/SQL語句中的SQL語句

declare  
   countnum number(2); //聲明變量  
begin  
   //into的作用把從數據中檢測出的數據賦值給哪個變量  
   select count(*) into countnum from emp; 
   dbms_output.put_line(countnum);  
end;  
/

注意:如果在select中沒有into語句會出現bug

declare  
   empno number(4);  
   ename varchar2(10);  
   job varchar2(9);  
begin  
   select empno,ename,job into empno,ename,job from emp;  
   dbms_output.put_line(empno||'/'||ename||'/'||job);  
end;  
/  

以上代碼中會出現bug bug原因是因爲定義的變量只可以存儲一個單獨的值,而你返回的是多個值.所以應該爲如下:

SQL> declare  
     empno number(4);  
     ename varchar2(10);  
     job varchar2(9);  
 begin  
     select empno,ename,job into empno,ename,job from emp where empno='7369'; //在這加上where條件了  
     dbms_output.put_line(empno||'/'||ename||'/'||job);  
 end;  
 /  

用%TYPE和%ROWTYPE類型的變量
在定義變量時處理可以使用oracle規定的數據類型外,還可以使用%TYPE和%ROWTYPE來定義變量.
%TYPE類型的變量是專門爲存儲在數據列中檢索到的值而創建的.對於使用%TYPE創建的變量,其數據類型由系統根據檢索的數據列的數據類型決定.
%ROWTYPE類型的變量,它可以一次存儲從數據庫檢索的一行數據。

當你不知道表中的數據類型是什麼時候?那你就考慮%TYPE來解決此問題。

SQL> declare  
         empno emp.empno%TYPE; //聲明的時候一定要加上表的中列  
         ename emp.ename%TYPE;  
         job   emp.job%TYPE;  
     begin  
          select empno,ename,job into empno,ename,job from emp where empno='7369';  
          dbms_output.put_line(empno||'/'||ename||'/'||job);  
     end;  
 / 

emp.empno%TYPE;解析:首先它到emp表中去查找empno列 %TYPE返回其數據的數據類型。

%TYPE的好處:
1、 可移植性高(當我們對錶的數據類型發生改變時,用戶不必考慮定義變量類型)
2、 用戶不必查看數據類型就可以定義變量能夠存儲檢索的數據。

%ROWTYPE

 SQL> declare  
      row_data emp%ROWTYPE;  
      begin  
         select * into row_data from emp where empno='7369';  
         dbms_output.put_line(row_data.empno||'/'||row_data.ename||'/'||row_data.job);  
      end;  
 / 

注意:如果定義了%rowtype類型的變量,該變量的結構與定義表的結構完全相同,查詢時必須使用*或者列舉全部的字段信息。

4、複合變量

複合變量可以將不同的數據類型的多個值存儲在一個單元中.由於複合數據類型可以有用戶根據需要定義其結構,所以複合數據類型也稱爲自定義數據類型。
PL/SQL提供了兩種類型的複合數據類型:
1、 記錄類型
在記錄類型中可以存儲多個標量值,與數據庫中的行相似
2、 記錄表類型
允許用戶在程序代碼中使用”表”,以便存儲多個行的數據。它只在程序運行期間有效。類似於程序代碼中集合|數組。

記錄類型:
必須使用TYPE語句定義記錄類型的語法聲明如下:

TYPE record_name is record(  
Field_name data_type[not null, :=default value]  
………  
);

與%Rowtype不同之處是
1、%rowtype查詢的是全部數據
2、記錄類型必須使用type語法格式聲明

//案例

SQL> declare  
        type empinfo is record( //聲明一個記錄類型  
          empno number(4),  
          ename varchar2(10),  
          job varchar2(9)  
        );  
        emp_data empinfo; //聲明一個記錄類型的變量  
     begin  
         select empno,ename,job into emp_data from emp where empno=7369; //查詢的結果賦值給定義的變量  
         dbms_output.put_line(emp_data.empno||'/'||emp_data.ename||'/'||emp_data.job);  
     end;  
/

記錄表類型
它可以處理多個記錄或多個行記錄。
1、 爲什麼使用記錄表類型呢?
因爲我們查詢的數據的往往需要返回多行記錄,所以需要記錄表類型。

2、 定義記錄表類型

TYPE table_name is table of data_type[not null]  
     Index by binary_integer;//主鍵的索引  
declare  
   type table_emp is table of emp%rowtype //創建一個表 此表的類型與emp表的類型一致  
   index by binary_integer;  

   type table_text is table of varchar2(20) //創建一個表 此表具有一個varchar2列的簡單表  
   index by binary_integer;  

   empt table_emp; //聲明記錄表類型的變量  
   tabtext table_text;  
begin  

案例:

SQL> declare  
       type table_emp is table of emp%rowtype  
       index by binary_integer;  
       empt table_emp;  
     begin  
       empt(1).ename:='wangyi';  
       dbms_output.put_line(empt(1).ename);  
     end;  
    /

//返回總記錄

SQL> declare  
       type table_emp is table of emp%rowtype  
       index by binary_integer;  
       empt table_emp;  
     begin  
       dbms_output.put_line(empt.count);  
     end;  
     /  

0//沒有記錄

//刪除的操作
表名.Delete(記錄數);

//檢索記錄變量
First:獲取第一個的索引
Next:下一個的索引 但是必須有參數
Last:最後一個的索引

SQL> declare  
        type table_emp is table of emp%rowtype  
        index by binary_integer;  
        empt table_emp;  
        i number(2):=1;  
     begin  
        while i<10  
        loop  
           empt(i).ename:='wangyi';  
           i:=i+1;  
        end loop;  
        dbms_output.put_line(empt.count);  
        empt.delete(2);  
        dbms_output.put_line(empt.count);  
        dbms_output.put_line(empt.first);  
        dbms_output.put_line(empt.next(2));  
        dbms_output.put_line(empt.last);  
     end;  
    /

9
8
1
3
9

//查詢數據庫的數據賦值給你創建的記錄表類型
分析一:

SQL> declare  
        type table_emp is table of emp%rowtype  
        index by binary_integer;  
        empt table_emp;  
        i number(10):=0;  
     begin  
        for rec in (select * from emp) loop  
           i:=i+1;  
           empt(i).ename:=rec.ename;  
        end loop;  
        dbms_output.put_line(empt.count);  
     end;  
     /

15

具體實現:
//把查詢的的數據全部賦值給記錄表類型

declare  
   type table_emp is table of emp%rowtype  
   index by binary_integer;  
   empt table_emp;  
   i number(10):=0;  
   j number(10):=1;  
begin  

   for rec in (select * from emp) loop  
     i:=i+1;  
     empt(i).empno:=rec.empno;  
     empt(i).ename:=rec.ename;  
     empt(i).job:=rec.job;  
     empt(i).mgr:=rec.mgr;  
     empt(i).hiredate:=rec.hiredate;  
     empt(i).sal:=rec.sal;  
     empt(i).comm:=rec.comm;  
     empt(i).deptno:=rec.deptno;  
    end loop;  

   while j<=empt.count loop  
   dbms_output.put_line(empt(j).empno||'/'||empt(j).ename||'/'||empt  
(j).job||'/'||empt(j).mgr||'/'||empt(j).hiredate||'/'||empt(j).sal||'/'||empt  
(j).comm||'/'||empt(j).deptno);  
   j:=j+1;  
 end loop;  
end;  
/  
SQL> declare  
       type table_emp is table of emp%rowtype  
       index by binary_integer;  
       empt table_emp;  
       i number(10):=0;  
       j number(10):=1;  
   begin  

       for rec in (select * from emp) loop  
          i:=i+1;  
          empt(i).empno:=rec.empno;  
          empt(i).ename:=rec.ename;  
          empt(i).job:=rec.job;  
          empt(i).mgr:=rec.mgr;  
          empt(i).hiredate:=rec.hiredate;  
          empt(i).sal:=rec.sal;  
          empt(i).comm:=rec.comm;  
          empt(i).deptno:=rec.deptno;  
         end loop;  

        dbms_output.put_line(empt.count);  

        while j<=empt.count loop  
        dbms_output.put_line(empt(j).empno||'/'||empt(j).ename||'/'||empt(j).job||'/'||empt(j).mgr||'/'||empt(j).hiredate||'/'||empt(j).sal||'/'||empt  (j).comm||'/'||empt(j).deptno);  
        j:=j+1;  
       end loop;  
    end;  
   /  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章