天天看點

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

 XXXX

  END LOOP;

5.變量指派

  V_TEST := 123;

6.用for in 使用cursor

  IS

  CURSOR cur IS SELECT * FROM xxx;

 FOR cur_result in cur LOOP

  BEGIN

   V_SUM :=cur_result.列名1+cur_result.列名2

  END;

 END LOOP;

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

  CLOSE C_USER;

8.用pl/sql developer debug

  連接配接資料庫後建立一個Test WINDOW

  在視窗輸入調用SP的代碼,F9開始debug,CTRL+N單步調試

1.在oracle中,資料表别名不能加as,如:

oracle 存儲過程的基本文法

select a.appname from appinfo a;-- 正确

oracle 存儲過程的基本文法

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

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

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

oracle 存儲過程的基本文法

  select af.keynode into kn from APPFOUNDATION af where af.appid=aid and af.foundationid=fid;-- 有into,正确編譯

oracle 存儲過程的基本文法

  select af.keynode from APPFOUNDATION af where af.appid=aid and af.foundationid=fid;-- 沒有into,編譯報錯,提示:Compilation 

oracle 存儲過程的基本文法

  Error: PLS-00428: an INTO clause is expected in this SELECT statement

oracle 存儲過程的基本文法
oracle 存儲過程的基本文法

3.在利用select...into...文法時,必須先確定資料庫中有該條記錄,否則會報出"no data found"異常。

   可以在該文法之前,先利用select count(*) from 檢視資料庫中是否存在該記錄,如果存在,再利用select...into...

4.在存儲過程中,别名不能和字段名稱相同,否則雖然編譯可以通過,但在運作階段會報錯

oracle 存儲過程的基本文法

 select keynode into kn from APPFOUNDATION where appid=aid and foundationid=fid;-- 正确運作

oracle 存儲過程的基本文法

select af.keynode into kn from APPFOUNDATION af where af.appid=appid and af.foundationid=foundationid;-- 運作階段報錯,提示

oracle 存儲過程的基本文法

ORA-01422:exact fetch returns more than requested number of rows

oracle 存儲過程的基本文法

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

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

oracle 存儲過程的基本文法

create table A(

oracle 存儲過程的基本文法

id varchar2(50) primary key not null,

oracle 存儲過程的基本文法

vcount number(8) not null,

oracle 存儲過程的基本文法

bid varchar2(50) not null -- 外鍵 

oracle 存儲過程的基本文法

);

如果在存儲過程中,使用如下語句:

oracle 存儲過程的基本文法

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

如果A表中不存在bid="xxxxxx"的記錄,則fcount=null(即使fcount定義時設定了預設值,如:fcount number(8):=0依然無效,fcount還是會變成null),這樣以後使用fcount時就可能有問題,是以在這裡最好先判斷一下:

oracle 存儲過程的基本文法

if fcount is null then

oracle 存儲過程的基本文法

    fcount:=0;

oracle 存儲過程的基本文法

end if;

這樣就一切ok了。

6.Hibernate調用oracle存儲過程

oracle 存儲過程的基本文法

        this.pnumberManager.getHibernateTemplate().execute(

oracle 存儲過程的基本文法
oracle 存儲過程的基本文法

                new HibernateCallback() ...{

oracle 存儲過程的基本文法

                    public Object doInHibernate(Session session)

oracle 存儲過程的基本文法
oracle 存儲過程的基本文法

                            throws HibernateException, SQLException ...{

oracle 存儲過程的基本文法

                        CallableStatement cs = session

oracle 存儲過程的基本文法

                                .connection()

oracle 存儲過程的基本文法

                                .prepareCall("{call modifyapppnumber_remain(?)}");

oracle 存儲過程的基本文法

                        cs.setString(1, foundationid);

oracle 存儲過程的基本文法

                        cs.execute();

oracle 存儲過程的基本文法

                        return null;

oracle 存儲過程的基本文法

                    }

oracle 存儲過程的基本文法

                });