Oracle存儲過程語法學習

Oracle存儲過程:html

1.1 第一個存儲過程java

--建立存儲過程node

create or replace procedure proc1(   sql

  p_para1 varchar2,   數據庫

  p_para2 out varchar2,   session

  p_para3 in out varchar2   oracle

)as    app

 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

這一點與其它高級語言都不一樣。它至關於java在參數前面加上final關鍵字。

 

OUT 參數:做爲輸出參數,須要注意,當一個參數被指定爲OUT類型時,就算在調用存儲過程以前對該參數進行了賦值,在存儲過程當中該參數的值仍然是null.

 

INOUT 是真正的按引用傳遞參數。便可做爲傳入參數也能夠做爲傳出參數。

 

-----------------------------------------------------------------------

-----------------------------------------------------------------------

Oracle存儲過程語法學習:

 

存儲過程建立語法:

       create or replace procedure 存儲過程名(param1 in type,param2 out type)

as

變量1 類型(值範圍);

變量2 類型(值範圍);

Begin

    Select count(*) into 變量1 from 表A where列名=param1;

    If (判斷條件) then

       Select 列名 into 變量2 from 表A where列名=param1;

       Dbms_output.Put_line(‘打印信息’);

    Elsif (判斷條件) then

       Dbms_output.Put_line(‘打印信息’);

    Else

       Raise 異常名(NO_DATA_FOUND);

    End if;

Exception

    When others then

       Rollback;

End;

 

注意事項:

一、  存儲過程參數不帶取值範圍,in表示傳入,out表示輸出

二、  變量帶取值範圍,後面接分號

三、  在判斷語句前最好先用count(*)函數判斷是否存在該條操做記錄

四、  用select 。。。into。。。給變量賦值

五、  在代碼中拋異經常使用 raise+異常名

 

以命名的異常:

命名的系統異常                          產生緣由

ACCESS_INTO_NULL                   未定義對象

CASE_NOT_FOUND                     CASE 中若未包含相應的 WHEN ,而且沒有設置ELSE 時

COLLECTION_IS_NULL                集合元素未初始化

CURSER_ALREADY_OPEN            遊標已經打開

DUP_VAL_ON_INDEX                   惟一索引對應的列上有重複的值

INVALID_CURSOR                       在不合法的遊標上進行操做

INVALID_NUMBER                        內嵌的 SQL 語句不能將字符轉換爲數字

NO_DATA_FOUND                        使用 select into 未返回行,或應用索引表未初始化的 

 

TOO_MANY_ROWS                      執行 select into 時,結果集超過一行

ZERO_DIVIDE                              除數爲 0

SUBSCRIPT_BEYOND_COUNT        元素下標超過嵌套表或 VARRAY 的最大值

SUBSCRIPT_OUTSIDE_LIMIT         使用嵌套表或 VARRAY 時,將下標指定爲負數

VALUE_ERROR                             賦值時,變量長度不足以容納實際數據

LOGIN_DENIED                             PL/SQL 應用程序鏈接到 oracle 數據庫時,提供了不正確的用戶名或密碼

NOT_LOGGED_ON                         PL/SQL 應用程序在沒有鏈接 oralce 數據庫的狀況下訪問數據

PROGRAM_ERROR                         PL/SQL 內部問題,可能須要重裝數據字典& pl./SQL系統包

ROWTYPE_MISMATCH                    宿主遊標變量與 PL/SQL 遊標變量的返回類型不兼容

SELF_IS_NULL                              使用對象類型時,在 null 對象上調用對象方法

STORAGE_ERROR                         運行 PL/SQL 時,超出內存空間

SYS_INVALID_ID                           無效的 ROWID 字符串

TIMEOUT_ON_RESOURCE               Oracle 在等待資源時超時

 

oracle 存儲過程的基本語法:

1.基本結構 
CREATE OR REPLACE PROCEDURE 存儲過程名字
(
    參數1 IN NUMBER,
    參數2 IN NUMBER
) IS
變量1 INTEGER :=0;
變量2 DATE;
BEGIN

END 存儲過程名字

2.SELECT INTO STATEMENT
  將select查詢的結果存入到變量中,能夠同時將多個列存儲多個變量中,必須有一條
  記錄,不然拋出異常(若是沒有記錄拋出NO_DATA_FOUND)
  例子: 
  BEGIN
  SELECT col1,col2 into 變量1,變量2 FROM typestruct where xxx;
  EXCEPTION
  WHEN NO_DATA_FOUND THEN
      xxxx;
  END;
  ...

3.IF 判斷
  IF V_TEST=1 THEN
    BEGIN 
       do something
    END;
  END IF;

4.while 循環
  WHILE V_TEST=1 LOOP
  BEGIN
       XXXX
  END;
  END LOOP;

5.變量賦值
  V_TEST := 123;

6.用for in 使用cursor

  ...
  IS
  CURSOR cur IS SELECT * FROM xxx;
  BEGIN
 FOR cur_result in cur LOOP
  BEGIN
   V_SUM :=cur_result.列名1+cur_result.列名2
  END;
 END LOOP;
  END;

7.帶參數的cursor
  CURSOR C_USER(C_ID NUMBER) IS SELECT NAME FROM USER WHERE TYPEID=C_ID;
  OPEN C_USER(變量值);
  LOOP
 FETCH C_USER INTO V_NAME;
 EXIT FETCH C_USER%NOTFOUND;
    do something
  END LOOP;
  CLOSE C_USER;

8.用pl/sql developer debug
  鏈接數據庫後創建一個Test WINDOW
  在窗口輸入調用SP的代碼,F9開始debug,CTRL+N單步調試

 

關於oracle存儲過程的若干問題備忘:

1.在oracle中,數據表別名不能加as,如:

select a.appname from appinfo a;-- 正確
select a.appname from appinfo as a;-- 錯誤

 也許,是怕和oracle中的存儲過程當中的關鍵字as衝突的問題吧

 

2.在存儲過程當中,select某一字段時,後面必須緊跟into,若是select整個記錄,利用遊標的話就另當別論了。

  select af.keynode into kn from APPFOUNDATION af where af.appid=aid and af.foundationid=fid;-- 有into,正確編譯
  select af.keynode from APPFOUNDATION af where af.appid=aid and af.foundationid=fid;-- 沒有into,編譯報錯,提示:Compilation 
  Error: PLS-00428: an INTO clause is expected in this SELECT statement

3.在利用select...into...語法時,必須先確保數據庫中有該條記錄,不然會報出"no data found"異常。

   能夠在該語法以前,先利用select count(*) from 查看數據庫中是否存在該記錄,若是存在,再利用select...into...

 

4.在存儲過程當中,別名不能和字段名稱相同,不然雖然編譯能夠經過,但在運行階段會報錯

 select keynode into kn from APPFOUNDATION where appid=aid and foundationid=fid;-- 正確運行
select af.keynode into kn from APPFOUNDATION af where af.appid=appid and af.foundationid=foundationid;-- 運行階段報錯,提示
ORA-01422:exact fetch returns more than requested number of rows

 

5.在存儲過程當中,關於出現null的問題

假設有一個表A,定義以下:

create table A(
id varchar2(50) primary key not null,
vcount number(8) not null,
bid varchar2(50) not null -- 外鍵 
);

若是在存儲過程當中,使用以下語句:

select sum(vcount) into fcount from A where bid='xxxxxx';

若是A表中不存在bid="xxxxxx"的記錄,則fcount=null(即便fcount定義時設置了默認值,如:fcount number(8):=0依然無效,fcount仍是會變成null),這樣之後使用fcount時就可能有問題,因此在這裏最好先判斷一下:

if fcount is null then
    fcount:=0;
end if;

這樣就一切ok了。

 

6.Hibernate調用oracle存儲過程

this.pnumberManager.getHibernateTemplate().execute(
       new HibernateCallback() {
             public Object doInHibernate(Session session)
                     throws HibernateException, SQLException {
                 CallableStatement cs = session.connection()
                         .prepareCall("{call modifyapppnumber_remain(?)}");
                 cs.setString(1, foundationid);
                 cs.execute();
                 return null;
              }
          });

 

 

這篇文章是對Oracle存儲過程學習的簡單總結。但願能帶給廣大博友的幫助,也很是感謝各位博友的支持!

如需轉載請註明出處:http://www.cnblogs.com/ZRJ-boke/p/6610524.html

相關文章
相關標籤/搜索