C ++ ODBC MS SQL"函数序列错误"当试图将jpg文件放入数据库时​​

时间:2016-08-10 11:38:30

标签: c++ odbc

我的程序将屏幕截图保存到jpg文件,然后它将获取这些jpg文件,打开它,并放入MS SQL数据库(进入VARBINARY [MAX]字段)。问题是 - 这些屏幕截图根据颜色有不同的大小。当我的节目采取"黑暗"截图 - 一切都好。但是当有更多" white"在屏幕上 - 我的函数返回"函数序列错误"。无法弄清楚我的代码有什么问题。这是整个功能(我在一些'弱的地方对我的评论):

int CreateDatabaseRecord(char *dateTime, char *userAccount, char* picturePath)
{

//preparing request 

    SQLLEN cbImageSize, lbytes;
    PTR pParmID;

    char SQL[1024] = "INSERT INTO screenshots (timedate, user_account, screenshot_path, pic) VALUES ('";

    strcat(SQL, dateTime);
    strcat(SQL, "', '");
    strcat(SQL, userAccount);
    strcat(SQL, "', '");
    strcat(SQL, picturePath);
    strcat(SQL, "', ?)");



    //working with jpg file
    string s = (string) picturePath;

    ifstream f;
    f.open(s.c_str(), ios::binary | ios::ate);
    size_t sz = (size_t) f.tellg();
    f.seekg(0, ios::beg);

    char *ptr = new char[sz]; 
    f.read(ptr, sz);
    f.close();

    SWORD cbBatch =  sz;
    lbytes = (SDWORD) sz;

    cbImageSize = SQL_LEN_DATA_AT_EXEC(lbytes);

    SQLSMALLINT DataType2, DecimalDigits2, Nullable2;

    SQLUINTEGER ParamSize2;


    ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
    if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
        LogSQLErrorDescription(SQL_HANDLE_STMT, stmt);
        return -9;
    }


    ret = SQLPrepareA(stmt, (SQLCHAR *) SQL, SQL_NTS);
    ret = SQLDescribeParam(stmt, 1, &DataType2, &ParamSize2, &DecimalDigits2, &Nullable2);


    if ((ret != SQL_SUCCESS) && (ret != SQL_SUCCESS_WITH_INFO) && (ret != SQL_NEED_DATA)) {

        LogSQLErrorDescription(SQL_HANDLE_STMT, stmt);
        return 9;

    }


    ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, DataType2, ParamSize2, 0, (VOID *) 1, 0,
                           &cbImageSize);



    if ((ret != SQL_SUCCESS) && (ret != SQL_SUCCESS_WITH_INFO) && (ret != SQL_NEED_DATA)) {

        LogWrite("SQLBindParam init failed");
        return 9;

    }






    ret = SQLExecDirect(stmt, (UCHAR *) SQL, SQL_NTS);
    if ((ret != SQL_SUCCESS) && (ret != SQL_SUCCESS_WITH_INFO) && (ret != SQL_NEED_DATA)) {

        LogSQLErrorDescription(SQL_HANDLE_STMT, stmt);
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);

        return 9;

    }


    ret = SQLParamData(stmt, &pParmID);
    if (ret == SQL_NEED_DATA) { 
    //putting data parts into DB      
        while (lbytes > cbBatch) {

            ret = SQLPutData(stmt, (SQLCHAR *) ptr, cbBatch);

            lbytes -= cbBatch;
            ptr += cbBatch;
        }


//"Function sequence error" raises here (when putting the final block):

        ret = SQLPutData(stmt, ptr, lbytes);


        delete[] ptr; //not shure about this
        ptr = 0; //and this


        if (ret != SQL_SUCCESS) {
            LogWrite("SQLParmData failed");
            LogSQLErrorDescription(SQL_HANDLE_STMT, stmt);
            SQLFreeHandle(SQL_HANDLE_STMT, stmt);

            return 9;

        }

    }
    else {
        LogSQLErrorDescription(SQL_HANDLE_STMT, stmt);
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        return 9;
    }

    ret = SQLParamData(stmt, &pParmID); //finalizing request


    if (ret != SQL_SUCCESS) {

        LogSQLErrorDescription(SQL_HANDLE_STMT, stmt);
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);


        return 9;

    }


    LogWrite("Database record successfully added");

    SQLFreeHandle(SQL_HANDLE_STMT, stmt);




return 0;
}

在循环中使用此函数的第二个问题 - 是内存泄漏。我的程序使用与每次循环迭代后的屏幕截图大小完全相同的内存量。为什么会这样?我delete[] ptr,我该怎么办?谢谢你的回答。

UPD。问题解决了。我所要做的只是添加一个字母=):

SDWORD cbBatch,而不是SWORD cbBatch

1 个答案:

答案 0 :(得分:0)

  

在循环中使用此函数的第二个问题 - 是内存泄漏。我的程序使用与每次循环迭代后的屏幕截图大小完全相同的内存量。为什么会这样?我删除[] ptr,我该怎么办?谢谢你的回答。

while (lbytes > cbBatch) { ... }循环中,您更改了ptr指针。您需要存储原始地址,以便之后能够删除整个分配的缓冲区。

E.g。取代

char *ptr = new char[sz];

char *buf = new char[sz];
char *ptr = buf;

并替换

delete[] ptr; //not shure about this
ptr = 0;      //and this

delete[] buf; 

这应该清除内存泄漏问题。