【Oracle】VC6.0使用 odbc 访问 Oracle 存储过程
环境说明
系统环境
- 系统:Windows XP
- IDE: Microsoft Visual C++ 6.0
- msado15.dll:
- 文件版本:
6.2.19041.3570
- 产品版本:
10.0.19041.3570
- 文件版本:
- 数据源驱动程序:
Oracle in OraClient11g_home1
-Oracle Datebase Client 11g Release 2 (11.2.0.1.0) for Microsoft Windows (32-Bit)
使用的对象 msado15.tlh
-
_ConnectionPtr
m_pConnection;HRESULT hr = m_pConnection.CreateInstance(“ADODB.Connection”);
-
_RecordsetPtr
m_pRecordset;m_pRecordset.CreateInstance(“ADODB.Recordset”);
-
_CommandPtr
m_pCommand;m_pCommand.CreateInstance(“ADODB.Command”);
-
_ParameterPtr
pInputParam;pInputParam.CreateInstance(__uuidof(Parameter));
Oracle 存储过程
Procedures
CREATE OR REPLACE PROCEDURE PRO_DISPENSER_DISPENSING
(
I_CHFM IN VARCHAR2
, ERR_NO OUT NUMBER
, ERR_MSG OUT VARCHAR2
) AS
BEGIN
ERR_NO := 1;
ERR_MSG := I_CHFM;
END PRO_DISPENSER_DISPENSING;
使用Oracle SQL Developer 调用存储过程
DECLARE
v_err_no NUMBER;
v_err_msg VARCHAR2(100);
BEGIN
PRO_DISPENSER_DISPENSING('少莫千华', v_err_no, v_err_msg);
DBMS_OUTPUT.PUT_LINE('Error number: ' || v_err_no);
DBMS_OUTPUT.PUT_LINE('Error message: ' || v_err_msg);
END;
VC6.0 完整代码
注意事项:以下代码可以会出现第一次调用成功,第二次调用失败的情况,建议每次调用都关闭链接,再重新打开链接再调用存储过程。
CADOManage* adb = new CADOManage();
LONG errorCode = adb->open();
if (errorCode !=0)
{
continue;
}
// 调用存储过程
errorCode = adb->execSQL2('入参1');
if (errorCode !=0)
{
adb->freeRecord();
adb->close();
continue;
}
adb->freeRecord();
adb->close();
long CADOManage::open()
{
//return open(param);
string connectMode = configUtil.getValue(cfghis_unMysql_DBConnectMode);
try
{
rootLogger->trace("function open start..............");
CoInitialize(0);
HRESULT hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象
if(SUCCEEDED(hr))
{
//dbType = "MYSQL";
_bstr_t connStr;
m_pConnection->CursorLocation=adUseClient;
for(int i=0;i< DBCMORA_NUM;i++)
{
if (egOracleCoonectUI[i] == connectMode)
{
string strConnect;
CString cstrConnect;
cstrConnect =stringToCString(egOracleCoonect[i]) ;
cstrConnect.Replace("myHost",stringToCString(ADODBparam.m_server));
cstrConnect.Replace("myUser",stringToCString(ADODBparam.m_uid));
cstrConnect.Replace("myPassword",stringToCString(ADODBparam.m_pwd));
cstrConnect.Replace("myDSName",stringToCString(ADODBparam.m_data));
if(ADODBparam.m_port == "")
ADODBparam.m_port = 1433;
cstrConnect.Replace("myPort",stringToCString(ADODBparam.m_port));
strConnect = CStringTostring(cstrConnect);
if (i== DBCMORA_ODBC1 || i==DBCMORA_OLEDBMS13 || i==DBCMORA_OLEDBOracle1)
{
m_pConnection->Open(_bstr_t(strConnect.c_str()),(_bstr_t)ADODBparam.m_uid.c_str(),(_bstr_t)ADODBparam.m_pwd.c_str(),adConnectUnspecified);
}
else if (i== DBCMORA_ODBC3)
{
m_pConnection->Open(_bstr_t(strConnect.c_str()),(_bstr_t)_T(""),(_bstr_t)_T(""),adModeUnknown);
}
else
{
m_pConnection->Open(_bstr_t(strConnect.c_str()),(_bstr_t)_T(""),(_bstr_t)_T(""),adConnectUnspecified);
}
break;
}
}
bOpen= true;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pCommand.CreateInstance("ADODB.Command");
m_pCommand->ActiveConnection = m_pConnection;
}
}
catch(_com_error e)///捕捉异常
{
string errormessage;
errormessage = "连接ADO数据库失败!\r错误信息:";
errormessage +=e.ErrorMessage();
rootLogger->fatal(errormessage);
// AfxMessageBox(errormessage.c_str());///显示错误信息
//bOpen= false;
return ER_DB_CONNECT;
}
rootLogger->trace("function open end..............");
return 0;
}
long CADOManage::execSQL2(const string &sqlText)
{
try{
rootLogger->trace("function execSQL start..............");
mute->Lock();
int nRet = 0;
if (sqlText == "")
{
rootLogger->warn("no SQL text!..............");
mute->Unlock();
return WM_NO_SQLTEXT;
}
freeRecord();
rootLogger->debug("sqlText = " + sqlText);
//设置命令类型
m_pCommand->CommandType = adCmdStoredProc;
//设置存储过程名称
m_pCommand->CommandText =_bstr_t("pro_dispenser_dispensing");
m_pCommand->put_CommandTimeout(60);
_ParameterPtr pInputParam,pOutputParam1,pOutputParam2;
pInputParam.CreateInstance(__uuidof(Parameter));
pOutputParam1.CreateInstance(__uuidof(Parameter));
pOutputParam2.CreateInstance(__uuidof(Parameter));
//设置入参 i_cfhm 名称、数据类型、输入/输出、长度、内容
pInputParam = m_pCommand->CreateParameter(_bstr_t("i_cfhm"), adVarChar, adParamInput, sqlText.length(), sqlText.c_str());
pInputParam->Value = _variant_t(sqlText.c_str());
//设置出参1 err_no 名称、数据类型、输入/输出、长度
pOutputParam1 = m_pCommand->CreateParameter(_bstr_t("err_no"), adInteger, adParamOutput,10);
//设置出参2 err_msg 名称、数据类型、输入/输出、长度
pOutputParam2 = m_pCommand->CreateParameter(_bstr_t("err_msg"), adVarChar, adParamOutput, 1024);
pOutputParam2->Size = 1024;
//添加入参1 到 命令
m_pCommand->Parameters->Append(pInputParam);
//添加入出参1 到 命令
m_pCommand->Parameters->Append(pOutputParam1);
//添加入出参2 到 命令
m_pCommand->Parameters->Append(pOutputParam2);
//以存储过程的形式adCmdStoredProc 执行命令
m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdStoredProc);
_variant_t errNoValue = pOutputParam1->Value;
_variant_t errMsgValue = pOutputParam2->Value;
// 转换为具体的类型
long errNo = errNoValue.lVal;
CString temp;
temp.Format(_T("%ld"), errNo);
MessageBox(NULL, temp, _T("err_no"), MB_OK);
if (errMsgValue.bstrVal != NULL)
{
_bstr_t errMsg = errMsgValue.bstrVal;
string temp(errMsg);
}
m_pCommand
->Parameters->Release();
pInputParam->Release();
pOutputParam1->Release();
pOutputParam2->Release();
mute->Unlock();
rootLogger->trace("function execSQL end..............");
}
catch (_com_error e) {
string errormessage = e.ErrorMessage();
rootLogger->error("failed to execute SQL:" + errormessage);
rootLogger->error("failed sql = " + sqlText);
mute->Unlock();
return ER_EXECUTE_SQL;
}
return 0;
}
报错情况
使用 m_pCommand->Execute(NULL, NULL,adCmdStoredProc)
调用Oracle存储过程时遇到了异常。
- 数据源驱动程序:
Oracle in OraClient12Home1_32bit
这种情况可能是由于不同版本的Oracle
驱动与msado15.dll
之间的兼容性问题导致的。不同版本的驱动程序和库文件可能具有不同的接口和行为,因此在使用不同版本的驱动程序时可能会出现不兼容的情况。
解决此问题的一种方法是确保使用的Oracle驱动程序
与msado15.dll
版本兼容。您可以尝试以下解决方案:
- 更换
msado库
- 确认您的代码中使用的是与Oracle驱动程序
版本相匹配的msado15.dll
库文件。如果您使用的是Oracle in OraClient12Home1_32bit
驱动程序,尝试使用与该驱动程序版本相对应的msado15.dll
库文件。 - 如果您无法找到与Oracle驱动程序版本完全匹配的
msado15.dll
库文件,可以尝试升级或降级Oracle驱动程序
版本,如:Oracle in OraClient11g_home1
,以确保与可用的msado15.dll
库文件兼容。 - 另外,您还可以考虑使用其他的数据库连接库或方法来连接和调用Oracle存储过程。例如,可以尝试使用
Oracle
提供的官方的ODBC驱动程序
或其他第三方的数据库连接库
,以避免与msado15.dll
版本不兼容的问题。
Microsoft C++ 异常: long,位于内存位置
0x75FOD982 处(位于 OracleTest.exe 中)发的异常: Microsoft C++ 异常: long,位于内存位置 0x00E6D88C 处。
0x75FOD982 处(位于 OracleTest.exe 中)发的异常: Microsoft C++ 异常: long,位于内存位置 0x0133D9A4 处。