oracle預存程序常用的技巧(詳)_oracle

來源:互聯網
上載者:User

我們在進行pl/sql編程時打交道最多的就是預存程序了。預存程序的結構是非常的簡單的,我們在這裡除了學習預存程序的基本結構外,還會學習編寫預存程序時相關的一些實用的知識。如:遊標的處理,異常的處理,集合的選擇等等

1.預存程序結構

1.1 第一個預存程序

create or replace procedure proc1(   p_para1 varchar2,   p_para2 out varchar2,   p_para3 in out varchar2  )as   v_name varchar2(20);  begin   v_name := '張三丰';   p_para3 := v_name;   dbms_output.put_line('p_para3:'||p_para3);  end; 

上面就是一個最簡單的預存程序。一個預存程序大體分為這麼幾個部分:

建立語句:create or replace procedure 預存程序名

如果沒有or replace語句,則僅僅是建立一個預存程序。如果系統存在該預存程序,則會報錯。Create or replace procedure 如果系統中沒有此預存程序就建立一個,如果系統中有此預存程序則把原來刪除掉,重新建立一個預存程序。

預存程序名定義:包括預存程序名和參數列表。參數名和參數類型。參數名不能重複, 參數傳遞方式:IN, OUT, IN OUT

IN 表示輸入參數,按值傳遞方式。

OUT 表示輸出參數,可以理解為按引用傳遞方式。可以作為預存程序的輸出結果,供外部調用者使用。

IN OUT 即可作輸入參數,也可作輸出參數。

參數的資料類型只需要指明類型名即可,不需要指定寬度。

參數的寬度由外部調用者決定。
過程可以有參數,也可以沒有參數

變數聲明塊:緊跟著的as (is )關鍵字,可以理解為pl/sql的declare關鍵字,用於聲明變數。

變數聲明塊用於聲明該預存程序需要用到的變數,它的範圍為該預存程序。另外這裡聲明的變數必須指定寬度。遵循PL/SQL的變數聲明規範。

過程語句塊:從begin 關鍵字開始為過程的語句塊。預存程序的具體邏輯在這裡來實現。

異常處理塊:關鍵字為exception ,為處理語句產生的異常。該部分為可選

結束塊:由end關鍵字結果。

1.2 預存程序的參數傳遞方式

預存程序的參數傳遞有三種方式:IN,OUT,IN OUT .

IN 按值傳遞,並且它不允許在預存程序中被重新賦值。如果預存程序的參數沒有指定存參數傳遞類型,預設為IN

create or replace procedure proc1(   p_para1 varchar2,   p_para2 out varchar2,   p_para3 in out varchar2  )as   v_name varchar2(20);  begin   p_para1 :='aaa';   p_para2 :='bbb';   v_name := '張三丰';   p_para3 := v_name;   dbms_output.put_line('p_para3:'||p_para3);   null;  end;      Warning: Procedure created with compilation errors   SQL> show error;  Errors for PROCEDURE LIFEMAN.PROC1:   LINE/COL ERROR  -------- ----------------------------------------------------------------------  8/3   PLS-00363: expression 'P_PARA1' cannot be used as an assignment target  8/3   PL/SQL: Statement ignored 

這一點與其它進階語言都不同。它相當於java在參數前面加上final關鍵字。

OUT 參數:作為輸出參數,需要注意,當一個參數被指定為OUT類型時,就算在調用預存程序之前對該參數進行了賦值,在預存程序中該參數的值仍然是null.

create or replace procedure proc1(   p_para1 varchar2,   p_para2 out varchar2,   p_para3 in out varchar2  )as   v_name varchar2(20);  begin   v_name := '張三丰';   p_para3 := v_name;   dbms_output.put_line('p_para1:'||p_para1);   dbms_output.put_line('p_para2:'||p_para2);   dbms_output.put_line('p_para3:'||p_para3);  end;   SQL> var p1 varchar2(10);  SQL> var p2 varchar2(10);  SQL> var p3 varchar2(10);  SQL> exec :p1 :='aaaa';  SQL> exec :p2 :='bbbb';  SQL> exec :p3 :='cccc';  SQL> exec proc1(:p1,:p2,:p3);  p_para1:aaaa  p_para2:  p_para3:張三丰  SQL> exec dbms_output.put_line(:p2);    PL/SQL procedure successfully completed  p2  --------- 

INOUT 是真正的按引用傳遞參數。即可作為傳入參數也可以作為傳出參數。

1.3 預存程序參數寬度  

create or replace procedure proc1(   p_para1 varchar2,   p_para2 out varchar2,   p_para3 in out varchar2  )as   v_name varchar2(2);  begin   v_name := p_para1;  end;  SQL> var p1 varchar2(10);  SQL> var p2 varchar2(20);  SQL> var p3 varchar2(30);  SQL> exec :p1 :='aaaaaa';  SQL> exec proc1(:p1,:p2,:p3);  ORA-06502: PL/SQL: numeric or value error: character string buffer too small  ORA-06512: at "LIFEMAN.PROC1", line 8 ORA-06512: at line 1 

首先,我們要明白,我們無法在預存程序的定義中指定儲存參數的寬度,也就導致了我們無法在預存程序中控制傳入變數的寬度。

這個寬度是完全由外部傳入時決定的。

我們再來看看OUT類型的參數的寬度。

create or replace procedure proc1(   p_para1 varchar2,   p_para2 out varchar2,   p_para3 in out varchar2  )as   v_name varchar2(2);  begin   p_para2 :='aaaaaaaaaaaaaaaaaaaa';  end;  SQL> var p1 varchar2(1);  SQL> var p2 varchar2(1);  SQL> var p3 varchar2(1);  SQL> exec :p2 :='a';  SQL> exec proc1(:p1,:p2,:p3); 

 在該過程中,p_para2被賦予了20個字元a.

而在外部的調用過程中,p2這個參數僅僅被定義為varchar2(1).

而把p2作為參數調用這個過程,卻並沒有報錯。而且它的真實值就是20個a

SQL> select dump(:p2) from dual;  DUMP(:P2)  ---------------------------------------------------------------------------  Typ=1 Len=20: 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97 p2  ---------  aaaaaaaaaaaaaaaaaaaa 

 再來看看IN OUT參數的寬度  

create or replace procedure proc1(   p_para1 varchar2,   p_para2 out varchar2,   p_para3 in out varchar2  )as   v_name varchar2(2);  begin   p_para3 :='aaaaaaaaaaaaaaaaaaaa';  end;  SQL> var p1 varchar2(1);  SQL> var p2 varchar2(1);  SQL> var p3 varchar2(1);  SQL> exec proc1(:p1,:p2,:p3); 

執行這個過程,仍然正確執行。

可見,對於IN參數,其寬度是由外部決定。

對於OUT 和IN OUT 參數,其寬度是由預存程序內部決定。

因此,在寫預存程序時,對參數的寬度進行說明是非常有必要的,最明智的方法就是參數的資料類型使用%type。這樣雙方就達成了一致。

1.3 參數的預設值

預存程序的參數可以設定預設值

create or replace procedure procdefault(p1 varchar2,                      p2 varchar2 default 'mark')  as  begin   dbms_output.put_line(p2);  end;  SQL> set serveroutput on;  SQL> exec procdefault('a'); mark 

可以通過default 關鍵字為預存程序的參數指定預設值。在對預存程序調用時,就可以省略預設值。
需要注意的是:預設值僅僅支援IN傳輸類型的參數。OUT 和 IN OUT不能指定預設值

對於有預設值的參數不是排在最後的情況。

create or replace procedure procdefault2(p1 varchar2 default 'remark',                      p2 varchar2 )  as  begin   dbms_output.put_line(p1);  end; 

第一個參數有預設值,第二個參數沒有。如果我們想使用第一個參數的預設值時

exec procdefault2('aa'); 

這樣是會報錯的。

那怎麼變呢?可以指定參數的值。

SQL> exec procdefault2(p2 =>'aa'); remark 

這樣就OK了,指定aa傳給參數p2

2. 預存程序內部塊

2.1 內部塊

我們知道了預存程序的結構,語句塊由begin開始,以end結束。這些塊是可以嵌套。在語句塊中可以嵌套任何以下的塊。

Declare … begin … exception … end;  create or replace procedure innerBlock(p1 varchar2)  as   o1 varchar2(10) := 'out1';  begin   dbms_output.put_line(o1);   declare    inner1 varchar2(20);   begin    inner1 :='inner1';    dbms_output.put_line(inner1);     declare     inner2 varchar2(20);    begin     inner2 := 'inner2';     dbms_output.put_line(inner2);    end;   exception    when others then     null;   end;  end; 

需要注意變數的範圍。

3.預存程序的常用技巧

3.1 哪種集合?

我們在使用預存程序的時候經常需要處理記錄集,也就是多條資料記錄。分為單列多行和多列多行,這些類型都可以稱為集合類型。我們在這裡進行比較這些集合類型,以便於在編程時做出正確的選擇。

索引表,也稱為pl/sql表,不能儲存於資料庫中,元素的個數沒有限制,下標可以為負值。

type t_table is table of varchar2(20) index by binary_integer;   v_student t_table; 

varchar2(20)表示存放元素的資料類型,binary_integer表示元素下標的資料類型。

巢狀表格,索引表沒有 index by子句就是巢狀表格,它可以存放於資料中,元素個數無限,下標從1開始,並且需要初始化

type t_nestTable is table of varchar2(20);  v_class t_nestTable ; 

僅是這樣聲明是不能使用的,必須對巢狀表格進行初始化,對巢狀表格進行初始化可以使用它的建構函式

v_class :=t_nestTable('a','b','c');

以上敘述就是本文的全部內容,希望對大家學習oracle預存程序有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.