VC呼叫儲存過程的通用方法(ORACLE篇)
先對上一篇呼叫SQLServer的儲存過程作一點補充,就是如果儲存過程裡有Insert,update,delete等操作,最後返回結果集,按示例程式碼有可能得不到資料,因為返回的資料有可能不在第一個結果集,需要進行遍歷:
long lngRec = 0;
_RecordsetPtr Rs = m_Rs; //m_Rs為呼叫儲存過程返回的結果集
while(Rs)
{
//結果集的處理,有無資料的判斷,資料處理等
while(!m_Rs->EndOfFile)
{
//...
}
Rs = Rs->NextRecordset((VARIANT *)lngRec);
}
呼叫ORACLE的儲存過程,VC的呼叫程式碼不需要變動,但需要對ORACLE的儲存過程和呼叫的SQL語句進行一些調整。
首先,連線字串不能用ODBC,即連線字串不能是
"Driver={Microsoft ODBC for Oracle};Server=OracleServer.world;Uid=Username;Pwd=asdasd;"
這種形式,而應該是類似:
"Provider=MSDAORA.1;Password=asdasd;User ID=Username;Data Source=world;Persist Security Info=True"
然後是儲存過程的調整,ORACLE儲存過程怎麼返回結果集網上的文章已經很多了,需要用到包,隨便摘錄一個:
CREATE OR REPLACE PACKAGE pkg_test
AS
TYPE myrctype IS REF CURSOR;
PROCEDURE get (p_id NUMBER, p_rc OUT myrctype);
END pkg_test;
/
CREATE OR REPLACE PACKAGE BODY pkg_test
AS
PROCEDURE get (p_id NUMBER, p_rc OUT myrctype)
IS
sqlstr VARCHAR2 (500);
BEGIN
IF p_id = 0 THEN
OPEN p_rc FOR
SELECT ID, NAME, sex, address, postcode, birthday
FROM student;
ELSE
sqlstr :=
'select id,name,sex,address,postcode,birthday
from student where id=:w_id';
OPEN p_rc FOR sqlstr USING p_id;
END IF;
END get;
END pkg_test;
/
其實不用包也可以,直接建立get,只需要把最後一個引數p_rc的型別改為sys_refcursor就可以了。
最後是SQL語句的調整,SQLServer是直接get 0就可以,ORACLE必須這樣呼叫:
{call get(0)}
即執行:
m_Rs->Open("{call get(0)}",(IDispatch*)(m_Conn->m_Conn),adOpenStatic, adLockReadOnly,adCmdText);
get雖然有兩個引數,但是SQL語句裡這個最後的輸出引數是可以不用寫的。
{call 儲存過程名(輸入引數1,輸入引數2,...)}這樣的SQL語句在SQLServer和ORACLE是都能得到返回結果集的,因此只要把SQL語句改成這種形式,程式程式碼不需要修改,就可以同時支援SQLServer和ORACLE的儲存過程的呼叫了。