1

BLOB をデータベースに挿入しようとしています。このために、私は c++ と Microsoft ODBC driver を使用しています。

アプリは 4000 ビット未満のファイルで問題なく動作します。4000 バイトを超える、つまり 3,9 KB のファイルを挿入しようとすると、次のように返されます: ORA-01460: 未実装または不合理な変換が要求されました。

データベースは oracle 11.2.0 です。インターネットで解決策を検索しましたが、何も見つかりません。

どうすればこの問題を解決できますか? 私に何ができる ?

私の挿入機能のコードは次のとおりです。

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