1

我正在尝试将 blob 插入数据库。为此,我使用 c++ 和 microsoft ODBC 驱动程序。

该应用程序适用于少于 4000 位的文件。当我试图插入一个超过 4000 字节(即 3.9 KB)的文件时,它会返回:ORA-01460:未实现或不合理的转换请求。

数据库是 oracle 11.2.0 。我已经在 internat 中搜索了解决方案,但没有找到。

我该如何解决这个问题?我能做些什么 ?

我的插入函数的代码是:

try{
    CString strSqlStat(szSqlStat);

    if(IsConnectionDead())
    {
        if(!Reconnect())
            return ERR_RECONNECT_FAILED;
    }

    CFileException exFile;
    CFile sourceFile;
    if(!sourceFile.Open(szFilePath, CFile::modeRead | CFile::shareDenyNone, &exFile))
        return ERR_BLOB_READFILE;

    int nrBytesToRead = (int)sourceFile.GetLength();
    char* pData = new char[nrBytesToRead+1];

    DWORD nrBytesRead;

    if(!ReadFile((HANDLE)sourceFile.m_hFile,pData,nrBytesToRead, &nrBytesRead, NULL))
    {
        delete pData;
        return ERR_BLOB_READFILE;
    }

    sourceFile.Close();

    if(nrBytesRead == 0)//file empty
    {
        delete pData;
        return 0;
    }

    //variables
    SQLRETURN retCode; 
    SDWORD   cbTextSize, lbytes;
    lbytes = (SDWORD)nrBytesRead;
    cbTextSize = SQL_LEN_DATA_AT_EXEC(lbytes);
    PTR pParmID;
    SDWORD cbBatch = nrBytesRead;
    int rgbValue = 1;

    // Bind the parameter marker.
    retCode = retcode = SQLBindParameter(hstmt,  // hstmt
         1,                     // ipar
         SQL_PARAM_INPUT,            // fParamType
         SQL_C_BINARY,               // fCType
         SQL_LONGVARBINARY,           // FSqlType
         lbytes,                  // cbColDef
         0,                     // ibScale
         &rgbValue,       // rgbValue
         0,                     // cbValueMax
         &cbTextSize);            // pcbValue

    SqlError(hstmt,SQL_HANDLE_STMT,_T("WriteBlob"), _T("CTLSqlConnection"), _T("SQLBindParameter"));
    if(retCode != SQL_SUCCESS)
    {
        delete pData;

        if(!EndTransaction(FALSE))
            return ERR_ENDTRANSACTION_FAILED;
        else
            return -3;
    }

    //SQLExec       
    retcode = retCode = SQLExecDirect(hstmt,(SQLTCHAR*)szSqlStat, SQL_NTS);
    retcode = retCode = SQLParamData(hstmt, &pParmID);
        SQLRETURN ret; //ADI fix all warnings - including this var that is unreferenced - delete it if you don't use it
        SQLCHAR* SQLState; //ADI same here
        SQLINTEGER NativeError;
        SQLSMALLINT errmsglen;
        SQLWCHAR errmsg[255];
        SQLWCHAR errstate[50];


SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, (SQLWCHAR*)errstate, &NativeError, (SQLWCHAR*)errmsg, sizeof(errmsg), &errmsglen);


    if(retCode == SQL_NEED_DATA)
    {
        // Put final batch.
        SQLPutData(hstmt, pData, lbytes); 
    }
    else
    {
        delete pData;

        SqlError(hstmt,SQL_HANDLE_STMT,_T("WriteBlob"), _T("CTLSqlConnection"), _T("SQLExecDirect or SQLParamData"));
        if(!EndTransaction(FALSE))
            return ERR_ENDTRANSACTION_FAILED;
        else
            return -4;
    }

    delete pData;

    // Make final SQLParamData call.
    retcode = retCode = SQLParamData(hstmt, &pParmID);
    /*SQLRETURN ret; //ADI fix all warnings - including this var that is unreferenced - delete it if you don't use it
        SQLCHAR* SQLState; //ADI same here
        SQLINTEGER NativeError;
        SQLSMALLINT errmsglen;
        SQLWCHAR errmsg[255];
        SQLWCHAR errstate[50];
    */  

SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, (SQLWCHAR*)errstate, &NativeError, (SQLWCHAR*)errmsg, sizeof(errmsg), &errmsglen);

    if(SqlError(hstmt,SQL_HANDLE_STMT,_T("WriteBlob"), _T("CTLSqlConnection"), _T("The last SQLParamData")))
        if(!EndTransaction(FALSE))
            return ERR_ENDTRANSACTION_FAILED;
        else
            return -5;

    retcode = SQLCloseCursor(hstmt);

    if(!EndTransaction(TRUE))
        return ERR_ENDTRANSACTION_FAILED;

}catch(...){
    WRITEERRORINLOGFILE(_T("Error: An exception has been caught in WriteBlob."));
    return -10;
}

返回0;

}

等待您的答复。谢谢 。

4

0 回答 0