使用plsql developer創建存儲過程以及調試 原

前言~

      今天莫名的接到一個任務,需要使用oracle定時任務和oracle存儲過程來每日創建一個日誌表,由於小編呢尚未接觸過存儲過程和定時任務,所以今天學習了一番,特定來總結一下。望能給予一些未接觸過存儲過程的小夥伴一些幫助。

       今入今天的正題,首先要了解一下oracle的存儲過程,都有哪些結構,而plsql是一個輔助工具,是能幫助我們更輕鬆的實現存儲過程。

上述就是一個無參的存儲過程實例,一個存儲過程大體分爲這麼幾個部分:

1)、創建語句:create or replace procedure 存儲過程名稱 [authid current_user] 

         “”[]“”中括號的內容是可選的,其表示修改存儲過程,加入authid current_user時存儲過程可以使用role權限。否則會報ORA-01031權限不足。

       如果沒有or replace語句,那只是新建一個存儲過程,如果系統中存在相同的存儲過程,則會報錯,Create or replace procedure 如果系統中沒有此存儲過程就新建一個,如果系統中有此存儲過程則把原來刪除掉,重新創建一個存儲過程。

       存儲過程名定義:包括存儲過程名參數列表參數名參數類型。參數列表可不寫,如例子所示。參數名不能重複,並且每個參數之間用分號“   ;” 隔開, 參數傳遞方式:IN, OUT, IN OUT。如下面例子所示:

下面說明一下參數傳遞方式:

        in:表示輸入參數,調用存儲過程時從外面傳進來的,它的值不能修改。 

        out:表示輸出參數,當一個參數被指定爲OUT類型時,如果還未調用存儲過程之前對該參數進行了賦值,那麼在存儲過程中該參數的值仍然是null,但是如果在調用過程中對該參數進行賦值,那麼值不爲null。

        in out:表示輸入輸出參數,它的值可以修改。

參數的數據類型只需要指明類型名即可,不需要指定寬度。參數的寬度由外部調用者決定。過程可以有參數,也可以沒有參數。

我們看到例子中存在一個“”as“”,它表示變量聲明塊,可以理解爲plsql中的declare關鍵字,用於聲明變量。除了as外,還有is。變量聲明塊用於聲明該存儲過程需要用到的變量,它的作用域爲該存儲過程。另外這裏聲明的變量必須指定寬度。遵循PL/SQL的變量聲明規範。

       其中,as和is的區別:在視圖(VIEW)中只能用AS不能用IS;

                                           在遊標(CURSOR)中只能用IS不能用AS。

過程語句塊:從begin 關鍵字開始爲過程的語句塊。存儲過程的具體邏輯在這裏來實現。

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

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

2)、下面講解一下參數列表中參數的默認值

通過default 關鍵字爲存儲過程的參數指定默認值。在對存儲過程調用時,就可以省略默認值。

值得注意的是:默認值僅僅支持IN傳輸類型的參數。OUT 和 IN OUT不能指定默認值

上述情況是default關鍵字修飾的是最後一個參數,如果是修飾第一個參數呢?

如果我們想使用第一個參數的默認值時,exec procdefault2('aa'); 這樣是會報錯的。

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

SQL> exec procdefault2(p2 =>'aa');   這樣就OK了,指定aa傳給參數p2。

3)、繼續講解存儲過程內部塊

       我們知道了存儲過程的結構,語句塊由begin開始,以end結束。這些塊是可以嵌套。在語句塊中可以嵌套任何以下的塊:Declare … begin … exception … end;  

需要注意變量的作用域。  

4)、存儲過程中的循環

存儲過程的循環語句塊有:for...in...loop、while和loop循環。下面分別給予相關實例。

(1)、for...in...loop

實例一 循環遍歷遊標

create or replace procedure proc_test

as

cursor c1

is

select * from  dat_trade;

begin

for x in c1

loop

dbms_output.put_line (x.id);

end loop;

end proc_test;

實例二 根據數值進行循環

create or replace procedure proc_test (v_num in NUMBER)

as

begin

for x in 1..100 loop

dbms_output.put_line (x);

end loop;

end proc_test;

實例三 在過程裏指定輸入參數 v_num. 在調用過程時指定循環次數

create or replace procedure proc_test (v_num IN NUMBER)

as

begin

for x in 1 .. v_num

loop

dbms_output.put_line (x);

end loop;

end proc_test;

(2)、loop循環

LOOP

loop

delete from  orders

where senddate < to_char (add_months (sysdate, -3),'yyyy-mm-dd') and rownum < 1000;

exit when SQL%ROWCOUNT < 1;

commit;

end loop;

這裏的 SQL%ROWCOUNT 是隱士遊標。 除了這個,還有其他幾

個:%found,%notfound, %isopen。

(3)while循環

create or replace procedure proc_test (v_num in number)

as

i number := 1;

begin

while i < v_num

loop

begin

i := i + 1;

dbms_output.put_line (i);

end;

end loop;

end proc_test;

5)、 存儲過程中的判斷

存儲過程的判斷語句塊有:if 條件語句、case ... when ... end case兩種

下面給出實例:

(1)、單if實例(if...then...end if; && if...then...else...end if;)

實例一:

create or replace procedure pro_test is

--邏輯判斷變量

  exit_table_data varchar2(40);  --判斷表數據是否存在

--sql語句執行變量

  execu_sql varchar2(2000);

begin

  execu_sql := 'select count(*) from user';

  execute immediate execu_sql into exit_table_data;

  if exit_table_data=0 then

  execu_sql := 'insert into user values('大明')';

  execute immediate execu_sql;

  commit;

  end if;

end pro_test;

實例二:

create or replace procedure pro_test is

--邏輯判斷變量

  exit_table_data varchar2(40);  --判斷表數據是否存在

--sql語句執行變量

  execu_sql varchar2(2000);

begin

  execu_sql := 'select count(*) from user';

  execute immediate execu_sql into exit_table_data;

  if exit_table_data=0 then

  execu_sql := 'insert into user values('大明')';

  execute immediate execu_sql;

  commit;

  else

  execu_sql:= 'update user set username='大華'';

  execute immediate execu_sql;

  commit;

  end if;

end pro_test;

(2)、多if實例(if...then...elseif...then...else...end if;)

create or replace procedure proc_test (v_num in number)

as

begin

if v_num < 10

then

dbms_output.put_line (v_num);

elseif v_num > 10 and v_num < 50

then

dbms_output.put_line (v_num - 10);

else

dbms_output.put_line (v_num - 50);

end if;

end proc_test;

(2)、case ... when ... end case

實例一:

create or replace procedure proc_test (v_num in number)

as

begin

case v_num

when 1 then

dbms_output.put_line (v_num);

when 2 then

dbms_output.put_line (v_num);

when 3 then

dbms_output.put_line (v_num);

else null;

end case;

end proc_test;

6)、給變量賦值

       我們在參數列表定義輸出參數、輸入輸出參數yi,以及在參數名位置定義參數,可能都需要一個賦值操作,讓查詢sql的結果賦值或者定義輸入參數賦值等等,那麼我們可以使用什麼方法給這些參數賦值呢?

       下面列舉出一些常用的爲變量賦值的方法:

       1、直接法

使用“  :=  ” 的符號爲變量賦值,例如: v_pare := "0";

        2、select into

假如變量爲v_pare,那麼爲它賦值的語句爲:select count(*) into v_pare from user;

        3、execute immediate 變量名(查詢sql語句結果賦值給它的變量)into 變量名

例如:

   v_sqlfalg   := 'select count(*) from user_tables where table_name='''||v_tablename || '''';

   execute immediate v_sqlfalg into v_flag;

   其中,v_tablename、v_sqlfalg、v_flag都是變量;

select into和execute immediate的區別

       1、execute immediate 賦值的變量是通過select語句查詢出來的,而select into是直接賦值給變量的。

7)、存儲過程跳出循環

oracle存儲過程可以使用3種方法跳出循環,分別是return、exit、continue;

它們的區別爲:

        1、return是直接跳出存儲過程;

        2、如果存在多層循環,exit是直接跳出存儲過程的本次循環,而去執行上一級循環的循環條件;

        3、continue是本次循環後面的代碼部分不再執行,轉而執行本循環的下一次循環。

8)、Oracle存儲過程中是否需要寫commit的問題

是否需要在存儲過程中寫commit主要依據需求:

(1) 如果是不需要在存儲過程中進行提交,而是由調用程序負責提交或者回滾,那麼不需要在存儲過程中commit或者rollback。

(2) 如果不想由調用程序負責提交或者回滾,那麼就應該在存儲過程中進行commit或rollback; 

另外,如果是純後臺數據庫開發,一定要寫.只是寫的時機同樣是分爲兩種,一種是寫在過程裏面;另一種是寫在調用存儲過程之後. 而之所以要寫commit的原因是,Oracle的默認事務級別是READ COMMITED;默認情況下,Oracle是不會自動提交的,需要手動提交才ok.

9)、使用plsql創建存儲過程步驟

1、登錄plsql後,在對象框中找到“Procedures”,點擊右鍵,找到新建,如圖所示:

2、進入到新建界面,如圖所示:

3、最終就進入到存儲過程結構中,你要做的就是編寫存儲過程邏輯。

10)、使用plsql對存儲過程進行調試

1、在“Procedures”下拉列表中找到已經編寫好的存儲過程,點擊右鍵,找到“測試”,如圖所示:

2、PL\SQL會打開調試界面,圖中位置1的按鈕就是開始調試的按鈕,在調試之前要填寫輸入參數的值,位置2就是填寫參數的地方,如果有多個參數,會有多行參數框,按參數名填寫相應的參數即可,如果沒有參數,可以不填。

3、填寫完參數,單擊開始調試按鈕後,調試的界面會發生一些變化。圖中位置1的變化,說明存過已經處於執行狀態,別人不能再編譯或者執行。位置2的按鈕就是執行按鈕,單擊這個按鈕存過會執行完成或者遇到bug跳出,否則是不會停下來的,調試時不會用這個按鈕的。位置3的按鈕纔是關鍵——單步執行,就是讓代碼一行一行的執行,位置4的按鈕是跳出單步執行,等待下一個指令。

今天的課程就講解到這裏,如果有不懂的地方,或者有建議,麻煩下方留言!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章