1. 程式人生 > >黑馬程式設計師--Oracle學習_day06

黑馬程式設計師--Oracle學習_day06

 ----------  android培訓 、java培訓、期待與您交流! ----------


學習目標:1,理解oraclepl/sql的概念

  2,掌握pl/sql程式設計技術(包括編寫過程、函式、觸發器...

學習的必要性:

 1,提高應用程式的執行效能

 2,模組化的設計思想

 3,減少網路傳輸量

 4,提高安全性

        名言:程式要用靈魂,一定要讓你的東西做得好一些。

pl/sql的缺點:

 1,移植性不好

1pl/sql的介紹

pl/sqlprocedural  language/sql)是oracle在標準的sql語言上的擴充套件。pl/sql不僅允許嵌入sql語言,還可以定義變數種常量,允許使用條件語句和迴圈語句,允許使用例外處理各種錯誤,這樣使得它的功能變得更加強大。

a,過程,函式,觸發器是pl/sql編寫

b,過程,函式,觸發器是在oracle

c,pl/sql是非常強大的資料庫過程語言

d,過程,函式可以在java程式中呼叫

·sql plus開發工具

sql plusoracle公司提供的一個工具,這個之前介紹過的。

舉一個簡單的案例:

編寫一個儲存過程,該過程可以向某表中新增記錄。

·pl/sql  developer開發工具

pl/sql  developer是用於開發pl/sql塊的整合開發環境(ide,它是一個獨立的

產品,而不是oracle的一個附帶品。

舉一個簡單的案例:

編寫一個儲存過程,通過該過程可以刪除某表記錄。

     2pl/sql

的基礎

開發人員使用pl/sql編寫應用模組時,不僅需要掌握sql語句的編寫方法,還要要掌握pl/sql語句及語法規則。pl/sql程式設計可以使用變數和邏輯控制語句,從而可以編寫非常有用的功能模組。比如:分頁儲存過程模組、訂單處理儲存過程模組、轉賬儲存過程模組...而且如果使用pl/sql程式設計,我們可以輕鬆的完成非常複雜的查詢要求。

·簡單分類

----過程(儲存過程)

----函式

        塊(程式設計)

----觸發器

-----包 

 ·編寫規範

1)註釋

a) 單行註釋 --

select  * from  emp  where  empno=7788;--取得員工資訊

b)多行註釋     用  

/* ...*/  來標記

2)識別符號號的命名規範

a) 當定義變數時,建議用v_作為字首   v_sal

b) 當定義常量時,建議用c_作為字首   c_rate

c) 當定義遊標時,建議用_cursor作為字尾  emp_cursor

d) 當定義例外時,建議用 e_作為字首 e_error

   ·塊,是pl/sql的基本程式單元,編寫pl/sql程式實際上就是編寫pl/sql塊。

要完成相對簡單的應用功能,可以只需要編寫一個pl/sql;但是是如果要 想實現複雜的功能,可以需要在一個pl/sql塊中巢狀其它的pl/sql塊。

     1)塊結構示意圖

 pl/sql塊由三個部分構成:定義部分、執行部分、例外處理部分。

如下所示:

declear

/*定義部分-------定義常量、變數、遊標、例外、複雜資料型別*/

begin

/*執行部分-------要執行的pl/sql語句和sql語句*/

exception

/*例外處理部分------處理執行的各種錯誤*/

end;

 2)例項1只包括執行部分的pl/sql

set  serverout put   on    --開啟輸出選項

begin

dbms_outpput.put_line(‘hello’);

end;

相關說明:

dbms_outputoracle所提供的包,該包包含一些過程,put_line就是dbms_output的一個過程。

 3)例項2包含定義部分和執行部分的pl/sql

declare

v_ename  varchar2(5);  --定義字串變數

begin 

insert  ename  into  v_eanme  from  emp  where   empno=&no;

dbms_output.put_line(‘僱員名:’ || v_ename);

end;

相關說明:

&表示要接收從控制檯輸入的變數。

4)例項3包含定義部分、執行部分和例外處理部分

為了避免pl/sql程式的執行錯誤,提高pl/sql的健壯性,應該對可能出現的錯誤進行處理,這個很有必要:

a,比如例項2中,如果輸入了不存在的僱員號,應當做例外處理。

b,有時出現異常,希望用另外的邏輯處理,我們看看如何完成a

  的要求

相關說明:oracle事先預定義了一些例外,no_data_found就是找不到資料的例外。

·過程

過程用於執行特定的操作,當建立過程時,既可以指定輸入引數(in),也可以指定輸出引數(out)。通過在過程中使用輸入引數,可以將資料傳遞到執行部分;通過使用輸出引數,可以將執行部分的資料傳遞到應用環境,在sqlplus中可以使用create  procedure 命令來建立過程。

例項如下:

a,請考慮編寫一個過程,可以輸入僱員名,新工資  可以修改僱

   員的工資。

b,如何呼叫過程有兩種方法。exec   and  call

c,如何在java程式中呼叫一個儲存過程。

?如何使用過程返回值

·函式

函式用於的返回特定的資料,當建立函式時,在函式頭部必須包含return子句,而在函式體內必須包含return語句返回的資料。我們可以使用create  function  來建立函式。

實際案例:輸入僱員的姓名,返回該僱員的年薪

create  function  xp_fun2(xpName  varchar2) return

number is YearSal  number(7,2);

begin  --執行部分

select  sal*12+nvl(comm,0)*12  into  YearSal   from  emp  where   ename=xpName;

return  YearSal;

end;

sqlplus中呼叫函式

sql>var  result  number

sql>call  xp_fun2(‘SCOTT’)  into:result;

sql>print  result;

同樣我們可以在java程式中呼叫該函式

select  annual_income(‘SCOTT’)  from  dual;//這樣

可以通過

·包

包用於在邏輯上組合過程和函式,它由包規範和包體兩部分組成。

1)我們可以使用create  package命令來建立包:

例項:

                        create  package  xp_package  is 

 procedure  update_sal(name  varchar2,newsl  number);

function  annual_income(name  varchar2)  return  number;

end

包的規範只包含了過程和函式的說明,但沒有過程和函式的實現程式碼。包體用於實現規範中的過程和函式。

2)建立包體可以使用create  package  body命令。

create  package  body xp_package is

procedure update_sal(name  varchar2,newsal number) is 

           begin

update  emp  set  sal=newsal  where  ename=name;

   end;

function  annual_income(name  varchar2)

   return  number is  annual_salary number;

begin

    select  sal*12+nvl(comm,0)  into  annual_salary   

            from  emp  where  ename=name;

    return  annual_salary;

end;

end;

  3) 如何呼叫包的過程或是函式

當呼叫包的過程或是函式時,在過程和函式前需要帶有包名,如果需要訪問其它方案的包,還還需要在包名前加方案名。

如:

sql>call  sp_package.update_sal(‘SCOTT’,1500);

特別說明:

包是pl/sql中非常重要的部分,我們在使用過程分頁時,將會再次體驗它的威力呵呵。

·觸發器

觸發器是指隱含的執行的儲存過程。當定義觸發器時,必須要指定觸發的事件和觸發的操作,常用的觸發事件包括insert,update,delete語句,而觸發操作實際就是一個pl/sql塊。可以使用create  trigger來建立觸發器。

特別說明:

我們會在後面詳細為大家介紹觸發器的使用,因為觸發器是非常有用的,可維護資料庫的安全和一致性。

·定義並使用變數

在編寫pl/sal程式時,可以定義變數和常量;在pl/sal程式中包括有:

1)標題型別(scalar

標量:在編寫pl/sql塊時,如果要使用變數,需要定義部分定義變數。

pl/sql中定義變數和常量的語法如下:

  indentifier  constant  datatype  not  null  := default  expr;

              indentifier:名稱

  constant:指定常量,需要指定它的初始值,且其值是不能改變的。

  datatype:資料型別

  not  null:指定變數值不能為null

  := 給變數或是常量指定初始值

  default  用於指定初始值

 expr : 指定初始值的pl/sql表示式,可是文字值、其它變數、函式等。

              ·標量案例:

1定義一個變長字串

v_ename   varchar2(10);

2,定義一個小數,範圍-9999.99 ~ 9999.99

v_sal   number(6,2);

3,定義一個小數並給一個初始值為5.4 := pl/sql的賦值符號

v_sal2   number(6,2):=5.4;

4,定義一個日期型別的資料

v_hiredate  date;

5,定義一個布林變數,不能為空,初始值為false

v_valid   boolean  not  null  default  false;

案例:輸入員工號,顯示僱員姓名、工資、個人所得稅(0.03),說明變數的使用。

declare

c_tax_rate  number(3,2):=0.03;

v_ename  varchar2(5);

v_sal  number(7,2);

v_tax_sal  number(7,2);

 begin

  select ename,sal into  v_ename,v_sal  from  emp  where   empno=&no;

v_tax_sal:=v_sal*c_tax_rate;--計算所得稅

dbms_output.put_line('姓名是:'||v_ename||'工資:'||v_sal||'交稅: '||v_tax_sal);

 end;

·標量(scalar)使用%type型別

對於上面的pl/sql塊有一個問題:

就是如果員工的姓名超過了5個字元的話,就會有錯誤,為了降低pl/sql程式的維護工作量,可以使用%type屬性定義變數,這樣它會按照資料庫列來確定你定義的變數的型別和長度,

例如:識別符號名  表名.列名%type;

2)複合型別(composite,用於存放多個值的變數,主要包括這幾種:

a,pl/sql記錄

    類似與高階語言中的結構體,需要注意的是,當引用pl/sql記錄成員時,  

必須要加記錄變數作為字首(記錄變數.記錄成員)如下:

declare

type  emp_record_type  is  record(

name  emp.ename%type;

salary   emp.sal%type;

title  emp.job%type);

sp_record  emp_record_type;

begin

select  ename,sal,job  into  sp_record  from  emp  where  empno=7788;

dbms_output.put_line(‘員工名:’||sp_record.name);

end;

b,pl/sql

相當於高階語言中的陣列,但是需要注意的是在高階語言中陣列的下標不能為負數,而pl/sql是可以為負數的,並且元素的下標沒限制。例項如下:

declare

type  sp_table_type  is  table  of  emp.ename%type

index  by  binary_integer;

sp_table  sp_table_type;

begin

select  ename  into  sp_table(0)  from  emp  where  empno=7788;

dbms_output.put_line(‘員工:’||sp_table(0));

end;

說明:

sp_table_type  pl/sql表型別

emp.ename%type   指定表的元素的型別和長度

sp_table  pl/sql表變數

sp_table(0) 則表示下標為0的元素

c,巢狀表

d,varray

3)參照型別(reference

引數變數是指用於存放數值指標的變數,通過使用參照變數,可以使得應用程式共享相同物件,從而降低佔用的空間。在編寫pl/sql程式時,可以使用遊標變數(ref  cursor)和物件型別變數(ref  obj_type)兩種參照變數型別。

a,參照變數 ref  cursor遊標變數

  使用遊標時,定義遊標時不需要指定相應的select語句,但是當使用遊標時(open)需要指定select語句,這樣一個遊標就與一個select語句結合了。例項如下:

請使用pl/sql編寫一個塊,可以輸入部門號,並顯示該部門所有員工姓名和他的工資,在些基礎上,如果某個員工的工資低於200元,就增加100元。

declare

type  sp_emp_cursor  is  ref cursor;  --定義遊標型別

test_cursor  sp_emp_cursor;    --定義遊標變數

v_ename   emp.ename%type;    --定義兩個變數

v_sal   emp.sal%type;

begin

  --test_cursor和一個select結合

open  test_cursor  for  select  ename,sal  from  emp  where  deptno=&no;

  --迴圈取出

 loop

fetch  test_cursor  into  v_ename,v_sal;

--判斷工資高低,決定是否更新

if  v_sal<200  then  update  emp  set sal=v_sal+100 

       where  ename=v_ename;

--判斷是否test_cursor為空

exit  when  test_cursor%notfound;

dbms_output.put_line('姓名:'||v_ename||'工資:'||v_sal);

 end  loop;

end;

4)loblarge  object