周末閑來練練Oracle的存儲過程,還從來沒寫過,一寫立馬蒙逼。。。沒有對比就沒有傷害,SQL Server和SSMS真是方便啊
一、建立存儲過程
CREATE OR REPLACE PROCEDURE upCustomStat ( sAction VARCHAR2, dNewFromDate DATE, dNewToDate DATE, dOldFromDate DATE, dOldToDate DATE, sSQLText VARCHAR2 ) AS sSQL VARCHAR2(4000); sIntRegServer VARCHAR2(50); sIntRegDBName VARCHAR2(50); sIntRegLinkServer VARCHAR2(100); p_cur SYS_REFCURSOR; CaseID VARCHAR2(50); BEGIN OPEN p_cur FOR SELECT CASEID FROM Caseproject WHERE ROWNUM < 10; LOOP FETCH p_cur INTO CaseID; EXIT WHEN p_cur%NOTFOUND; dbms_output.put_line(CaseID); END LOOP; CLOSE p_cur; END;
1、END末尾沒有分號要報錯,又提示的亂七八槽,找了半天才找到
錯誤:PLS-00103: 出現符號 "end-of-file"在需要下列之一時: ; <an identifier> <a double-quoted delimited-identifier> current delete exists prior <a single-quoted SQL string> 符號 ";" 被替換為 "end-of-file" 后繼續。 行:1498
2、在存儲過程里面的語法錯誤,執行后不會提示,但存儲過程是編譯不通過的,這樣太不方便查原因了
3、要想實時查看錯誤的話,要在存儲過程上右鍵->編輯
4、編輯存儲過程有個問題,平時我們都是用.sql文件存起來的,右鍵編輯調試完成后,還要手動復制到.sql文件中,太不方便。
直接保存的話是存成.prc文件,用這種存起來倒是也可以,但SQL Server過來習慣了存.sql文件,也比較通用。
二、調用存儲過程
BEGIN UPCUSTOMSTAT ('按開發項目統計預售情況數據', TO_DATE('2016-07-01 00:00:00','YYYY-MM-DD HH24:MI:SS'), TO_DATE('2016-08-31 23:59:59','YYYY-MM-DD HH24:MI:SS'), NULL, NULL, NULL); END;
1、EXEC 存儲過程名不行,看網上說好像要在命令行模式下?
2、在PL/SQL里的SQL窗口,只能用BEGIN END里直接執行
3、時間參數,不能直接傳字符串,而是要轉換。。。SQL Server都能自動識別
=================================
以上是使用dbms_output.put_line輸出PRINT之類的文本,要輸出結果集要用游標
=================================
三、輸出結果集
1、存儲過程使用游標
CREATE OR REPLACE PROCEDURE upCustomStat ( sAction VARCHAR2, dNewFromDate DATE, dNewToDate DATE, dOldFromDate DATE, dOldToDate DATE, sSQLText VARCHAR2, p_cur OUT SYS_REFCURSOR ) AS sSQL VARCHAR2(4000); sIntRegServer VARCHAR2(50); sIntRegDBName VARCHAR2(50); sIntRegLinkServer VARCHAR2(100); BEGIN OPEN p_cur FOR SELECT * FROM Caseproject WHERE ROWNUM < 10; END upCustomStat;
2、調用時傳入游標
DECLARE p_cur SYS_REFCURSOR; BEGIN UPCUSTOMSTAT ('按開發項目統計預售情況數據', TO_DATE('2016-07-01 00:00:00','YYYY-MM-DD HH24:MI:SS'), TO_DATE('2016-08-31 23:59:59','YYYY-MM-DD HH24:MI:SS'), NULL, NULL, NULL, p_cur); END;
3、有了游標,按SQL Server慣性思維,一直想把結果集SELECT出來,搜了半天,看來是不行。。。只能手動輸出
四、SQL Command
PL/SQL的Command和SQL Plus的Command還不一樣。。。
SQL> var rset refcursor; SQL> exec getEmpByDept(10,:rset); SQL> print rset;
參照網上的這一段,在PL/SQL的命令行,會報【 REFCURSOR not supported】這個錯,不識別,要SQL Plus才可以
使用SQL Plus后,確實能夠根據游標把結果集查詢出來
五、定義游標
1、使用【sys_refcursor】,即和上面用法一樣,這個最方便
2、使用包來定義【ref cursor】,要多定義一個包頭,再在包體中定義存儲過程
StackOverFlow上有高手論述過,sys_refcursor其實就是事先定義好的ref cursor,專門為了方便的(少定義一個包頭),可以放心使用