以下代码有什么问题吗?我总是在m_pRecordSet = pCommand->Execute的时候出错
PLSQLRSet=1在数据库连接时已经指定
大概会是什么问题呢?困扰一天了~还请大家多多指教啊!以下这样的写法表明我2种参数都试过,正常情况下存储过程应该是adCmdStoredProc,但是Oracle的文档里面好像都是adCmdText
//pCommand->CommandType = adCmdStoredProc; 
pCommand->CommandType = adCmdText;
_CommandPtr pCommand;
pCommand.CreateInstance(__uuidof(Command));
m_pRecordSet.CreateInstance(__uuidof(Recordset));

_ParameterPtr  param1;    // 这里只用一个应该就OK了~~~~~~~
param1.CreateInstance(__uuidof(Parameter));
_ParameterPtr  param2;
param2.CreateInstance(__uuidof(Parameter));
_ParameterPtr  param3;
param3.CreateInstance(__uuidof(Parameter));
_ParameterPtr  param4;
param4.CreateInstance(__uuidof(Parameter));
_ParameterPtr  param5;
param5.CreateInstance(__uuidof(Parameter)); _variant_t varRet; /*
pkg_search.search(Recode_begin in number,
Recode_after in number,
Recode_count in out number,
pStr         in varchar2,
io_cursor    out sys_refcursor)
*/ pCommand->ActiveConnection = m_pConnection; 
//pCommand->CommandType = adCmdStoredProc; 
pCommand->CommandType = adCmdText; // pkg_search.search参数封装
param1 = pCommand->CreateParameter((_bstr_t)"Recode_begin", adNumeric, adParamInput, 8/*sizeof(double)*/, _variant_t(lStartNum));
param1->NumericScale = 1;
pCommand->Parameters->Append(param1); param2 = pCommand->CreateParameter((_bstr_t)"Recode_after", adNumeric, adParamInput, 8/*sizeof(double)*/, _variant_t(lEndNum));
param2->NumericScale = 1;
pCommand->Parameters->Append(param2); param3 = pCommand->CreateParameter((_bstr_t)"Recode_count", adNumeric, adParamInputOutput, 8/*sizeof(double)*/, _variant_t(lInNum));
param3->NumericScale = 1;
pCommand->Parameters->Append(param3); param4 = pCommand->CreateParameter((_bstr_t)"pStr", adVarChar/*adChar*/, adParamInput, 64, _variant_t(strSearchString));
pCommand->Parameters->Append(param4); // 在OLE DB的标准中,没有REF CURSOR类型的预定义数据类型,
// 因此在调用存储过程时,不能创建REF CURSOR类型的参数。
// 在ADO调用返回记录集的存储过程时,OLE DB自动为存储过程中REF CURSOR类型的传出参数返回记录集
// 该记录集可以赋值给一个Recordset对象。
//param5 = pCommand->CreateParameter((_bstr_t)"io_cursor", adVariant, adParamOutput, -1);
//pCommand->Parameters->Append(param5); // 使用 Command对象的CommandText 属性定义调用存储过程的命令。
// 当使用Command对象执行Oracle返回记录集存储过程时,须以odbc转义符调用格式来调用存储过程。
// 例如:{call credit_account(?,?)}。在这种格式中,传入和传出参数都用问号“?”来表示
//pCommand->CommandText = "PKG_SEARCH.search";   // 存储过程名
pCommand->CommandText = "{CALL PKG_SEARCH.search(?,?,?,?)}"; //m_pRecordSet->CursorType = adOpenStatic; 
//m_pRecordSet->LockType = adLockPessimistic;
//m_pConnection->CursorLocation = adUseClient; _variant_t vNULL; 
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;  //m_pRecordSet = pCommand->Execute(NULL, NULL, adCmdStoredProc);
m_pRecordSet = pCommand->Execute(&vNULL, &vNULL, adCmdText);      // 这里总是异常

解决方案 »

  1.   

    首先,请用try,catch捕获具体的错误信息
    其次,检查过程的参数类型和参数名是否一致
      

  2.   

    How to call an Oracle Stored Procedure that returns one or more REF CURSORS, using ADO from C++
    CREATE OR REPLACE
    PROCEDURE GetEmpRS1 (p_recordset1 OUT SYS_REFCURSOR, 
                  p_recordset2 OUT SYS_REFCURSOR,
                  PARAM IN STRING) AS
    BEGIN
      OPEN p_recordset1 FOR
      SELECT RET1 
        FROM MYTABLE
        WHERE LOOKUPVALUE > PARAM;  OPEN p_recordset2 FOR
      SELECT RET2
       FROM MYTABLE
       WHERE LOOKUPVALUE >= PARAM;
    END GetEmpRS1;
    _ConnectionPtr m_pConn;
    _RecordsetPtr pRecordset;
    _CommandPtr pCommand; 
    _ParameterPtr pParam1;//We will use pParam1 for the sole input parameter.//NOTE: We must not append (hence need not create)//the REF CURSOR parameters. If your stored proc has//normal OUT parameters that are not REF CURSORS, you need//to create and append them too. But not the REF CURSOR ones!
    //Hardcoding the value of i/p paramter in this example...
    _variant_t vt;
    vt.SetString("2");m_pConn.CreateInstance (__uuidof (Connection));
    pCommand.CreateInstance (__uuidof (Command));//NOTE the "PLSQLRSet=1" part in //the connection string. You can either//do that or can set the property separately using //pCommand->Properties->GetItem("PLSQLRSet")->Value = true;//But beware if you are not working with ORACLE, trying to GetItem()//a property that does not exist //will throw the adErrItemNotFound exception.
    m_pConn->Open (
      _bstr_t ("Provider=OraOLEDB.Oracle;PLSQLRSet=1;Data Source=XXX"), 
      _bstr_t ("CP"), _bstr_t ("CP"), adModeUnknown);
    pCommand->ActiveConnection = m_pConn;pParam1 = pCommand->CreateParameter( _bstr_t ("pParam1"), 
              adSmallInt,adParamInput, sizeof(int),( VARIANT ) vt);
    pCommand->Parameters->Append(pParam1);
    pRecordset.CreateInstance (__uuidof (Recordset));//NOTE: We need to specify the stored procedure name as COMMANDTEXT//with proper ODBC escape sequence.//If we assign COMMANDTYPE to adCmdStoredProc and COMMANDTEXT//to stored procedure name, it will not work in this case.//NOTE that in the escape sequence, the number '?'-s correspond to the//number of parameters that are NOT REF CURSORS.
    pCommand->CommandText = "{CALL GetEmpRS1(?)}";//NOTE the options set for Execute. It did not work with most other//combinations. Note that we are using a _RecordsetPtr object//to trap the return value of Execute call. That single _RecordsetPtr//object will contain ALL the REF CURSOR outputs as adjacent recordsets.
    pRecordset = pCommand->Execute(NULL, NULL, 
                 adCmdStoredProc | adCmdUnspecified );//After this, traverse the pRecordset object to retrieve all//the adjacent recordsets. They will be in the order of the//REF CURSOR parameters of the stored procedure. In this example,//there will be 2 recordsets, as there were 2 REF CURSOR OUT params.
    while( pRecordset !=NULL ) )
    {
        while( !pRecordset->GetadoEOF() )
        {
            //traverse through all the records of current recordset...    }
        long lngRec = 0;
        pRecordset = pRecordset->NextRecordset((VARIANT *)lngRec);
    }//Error handling and cleanup code (like closing recordset/ connection)//etc are not shown here.