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

前言~

      今天莫名的接到一個任務,須要使用oracle定時任務和oracle存儲過程來每日建立一個日誌表,因爲小編呢還沒有接觸過存儲過程和定時任務,因此今天學習了一番,特定來總結一下。望能給予一些未接觸過存儲過程的小夥伴一些幫助。sql

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

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

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

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

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

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

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

        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

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的結果賦值或者定義輸入參數賦值等等,那麼咱們可使用什麼方法給這些參數賦值呢?

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

       一、直接法

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

        二、select into

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

        三、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的區別

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

7)、存儲過程跳出循環

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

它們的區別爲:

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

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

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

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

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

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

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

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

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

一、登陸plsql後,在對象框中找到「Procedures」,點擊右鍵,找到新建,如圖所示:

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

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

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

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

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

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

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

相關文章
相關標籤/搜索