• 【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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    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;
    }		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    报错情况

    使用 m_pCommand->Execute(NULL, NULL,adCmdStoredProc)调用Oracle存储过程时遇到了异常。

    • 数据源驱动程序: Oracle in OraClient12Home1_32bit

    这种情况可能是由于不同版本的Oracle驱动与msado15.dll之间的兼容性问题导致的。不同版本的驱动程序和库文件可能具有不同的接口和行为,因此在使用不同版本的驱动程序时可能会出现不兼容的情况。
    解决此问题的一种方法是确保使用的Oracle驱动程序msado15.dll版本兼容。您可以尝试以下解决方案:

    1. 更换msado库 - 确认您的代码中使用的是与Oracle驱动程序版本相匹配的msado15.dll库文件。如果您使用的是Oracle in OraClient12Home1_32bit驱动程序,尝试使用与该驱动程序版本相对应的msado15.dll库文件。
    2. 如果您无法找到与Oracle驱动程序版本完全匹配的msado15.dll库文件,可以尝试升级或降级Oracle驱动程序版本,如:Oracle in OraClient11g_home1,以确保与可用的msado15.dll库文件兼容。
    3. 另外,您还可以考虑使用其他的数据库连接库或方法来连接和调用Oracle存储过程。例如,可以尝试使用Oracle提供的官方的ODBC驱动程序或其他第三方的数据库连接库,以避免与msado15.dll版本不兼容的问题。

    Microsoft C++ 异常: long,位于内存位置

    0x75FOD982 处(位于 OracleTest.exe 中)发的异常: Microsoft C++ 异常: long,位于内存位置 0x00E6D88C 处。

    在这里插入图片描述

    0x75FOD982 处(位于 OracleTest.exe 中)发的异常: Microsoft C++ 异常: long,位于内存位置 0x0133D9A4 处。

    在这里插入图片描述

  • 相关阅读:
    一维时间序列信号的改进小波降噪方法(MATLAB R2021B)
    MyBatisPlus 查询条件构造器(Wapper)
    刷题记录:牛客NC16708[NOIP2002]过河卒
    中端酒店迈入“30+”,维也纳酒店如何化解行业的三大难关
    OKHTTP拦截器:IPv4地址优先连接
    [附源码]计算机毕业设计springboot电商小程序
    【Spring Boot 集成应用】Redis的集成用法
    已解决 Bug——SyntaxError: Unexpected token o in JSON at position 1问题
    拒绝for循环,从take_along_axis开始
    cesium 图形标注圆形、正方形、多边形、椭圆等
  • 原文地址:https://blog.csdn.net/chenlu5201314/article/details/133996068