Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过ODBC在informix中插入BLOB时进行核心转储_C++_C_Odbc_Informix - Fatal编程技术网

C++ 通过ODBC在informix中插入BLOB时进行核心转储

C++ 通过ODBC在informix中插入BLOB时进行核心转储,c++,c,odbc,informix,C++,C,Odbc,Informix,在事务日志记录已打开的情况下连接到IDS的11.50版本: onstat -version Program Name: onstat Build Version: 11.50.UC5XE Build Number: N104 Build Host: ku Build OS: Linux kernel-2.6.9-34.ELsmp glibc-2.3.4-2.19 compat-glibc-2.3.2-95.30 Build Date: Thu Jul 15

在事务日志记录已打开的情况下连接到IDS的11.50版本:

onstat -version
Program Name:   onstat
Build Version:  11.50.UC5XE
Build Number:   N104
Build Host:     ku
Build OS:       Linux kernel-2.6.9-34.ELsmp glibc-2.3.4-2.19 compat-glibc-2.3.2-95.30
Build Date:     Thu Jul 15 12:44:25 CDT 2010
GLS Version:    glslib-4.50.UC6
在与IDS实例(RHEL 4.8 32位)相同的系统或运行CentOS 4.8 32位的远程系统上,通过3.50UC8版本的Connect驱动程序使用UnixODBC 2.2.11。每当我尝试将BLOB插入数据库时,我都会得到一个segfault

下面是演示问题的示例代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sqlext.h>

#define CONNECTION_STRING "<valid connection string>"

#define CREATE_TABLE "CREATE TABLE blob_test(id SERIAL, test BLOB)"
#define INSERT_BLOB "INSERT INTO blob_test(test) VALUES(?)"

#define BLOB_SIZE 4096

int main(int argc, const char ** args) {
    printf("Informix ODBC BLOB test.\n");

    int exitCode = 0;

    SQLHENV henv;
    SQLHDBC hdbc;
    SQLHSTMT hstmt;
    SQLLEN ind;
    SQLRETURN ret;

    char data[BLOB_SIZE];
    char * paramData = NULL;

    // Allocate environment handle
    if(!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv))) {
        printf("Failed to allocate environment handle.\n");
        goto exit;
    }

    if(!SQL_SUCCEEDED(SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0))) {
        printf("Failed to initialize environment handle.\n");
        goto cleanup_env;
    }

    // Connect
    if(!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc))) {
        printf("Failed to allocate connection handle.\n");
        goto cleanup_env;
    }

    if(!SQL_SUCCEEDED(SQLDriverConnectA(hdbc, NULL, 
            (SQLCHAR *)CONNECTION_STRING, SQL_NTS, 
            NULL, 0, NULL, SQL_DRIVER_COMPLETE))) {
        printf("Failed to connect.\n");
        goto cleanup_dbc;
    }
    printf("Connected.\n");

    // Allocate statement
    if(!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt))) {
        printf("Failed to allocate statement handle.\n");
        goto disconnect;
    }

    //Create table
    if(!SQL_SUCCEEDED(SQLExecDirectA(hstmt, 
            (SQLCHAR *)CREATE_TABLE, strlen(CREATE_TABLE)))) {
        printf("Failed to create table.\n");
        //continue anyway
    } else {
        printf("Created test table.\n");
    }

    //Prepare data
    memset(data, 0, BLOB_SIZE);

    //Prepare statement
    if(!SQL_SUCCEEDED(SQLPrepareA(hstmt, 
            (SQLCHAR *)INSERT_BLOB, strlen(INSERT_BLOB)))) {
        printf("Failed to prepare statement.\n");
        goto cleanup_stmt;
    }

    //Bind data
    ind = SQL_LEN_DATA_AT_EXEC(BLOB_SIZE);
    if(!SQL_SUCCEEDED(SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY,
            SQL_LONGVARBINARY, BLOB_SIZE, 0, &data, 0, &ind))) {
        printf("Failed to bind blob.\n");
        goto cleanup_stmt;
    }

    //Execute
    printf("Inserting BLOB.\n");
    ret = SQLExecute(hstmt);
    if(SQL_NEED_DATA == ret) {
        //send additional data
        ret = SQLParamData(hstmt, 
            reinterpret_cast<SQLPOINTER *>(&paramData));

        if(paramData != data) {
            printf("Warning, data pointers(%p,%p) do not match!\n", data, paramData);
        }

        while(SQL_NEED_DATA == ret) {
            ret = SQLPutData(hstmt, data, BLOB_SIZE);

            if(!SQL_SUCCEEDED(ret)) {
                printf("Error setting parameter data.\n");
                goto cleanup_stmt;
            }

            //Read the next parameter requiring data, if any
            /**
             * ===== CRASH HAPPENS ON THIS LINE =====
             */
            ret = SQLParamData(hstmt, 
                reinterpret_cast<SQLPOINTER *>(&paramData));            
        }
    }

    if(!SQL_SUCCEEDED(ret)) {
        printf("Failed to execute.\n");
        goto cleanup_stmt;
    }
    printf("Inserted blob data.\n");

cleanup_stmt:   
    printf("Freeing hstmt.\n");
    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
disconnect:
    printf("Disconnecting.\n");
    SQLDisconnect(hdbc);
cleanup_dbc:
    printf("Freeing hdbc.\n");
    SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
cleanup_env:
    printf("Freeing henv.\n");
    SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit:
    return exitCode;
}
和堆栈跟踪:

#0  0x00a07363 in memmove () from /lib/tls/libc.so.6
#1  0x001fccbe in _iwrite () from /opt/informix/lib/cli/iclit09b.so
#2  0x001fb431 in _iputpbuf () from /opt/informix/lib/cli/iclit09b.so
#3  0x00184c42 in _Odbcputpbuf () from /opt/informix/lib/cli/iclit09b.so
#4  0x00182cc8 in _OdbcPutChstrNoCsc () from /opt/informix/lib/cli/iclit09b.so
#5  0x00164b4f in _OdbcPutAsfLvarcharVal () from /opt/informix/lib/cli/iclit09b.so
#6  0x001acef8 in _OdbcExtBinary2IntSendrecv () from /opt/informix/lib/cli/iclit09b.so
#7  0x0016ca48 in _OdbcPutBindings () from /opt/informix/lib/cli/iclit09b.so
#8  0x0016c836 in _OdbcAssignInputParams () from /opt/informix/lib/cli/iclit09b.so
#9  0x0016d373 in _OdbcExecute () from /opt/informix/lib/cli/iclit09b.so
#10 0x0014c125 in _OdbcExecuteRow () from /opt/informix/lib/cli/iclit09b.so
#11 0x0014c3a4 in SQLParamData () from /opt/informix/lib/cli/iclit09b.so
#12 0x00b17f09 in SQLParamData () from /usr/lib/libodbc.so.1
#13 0x08048a16 in main ()
最后,从odbc驱动程序进行跟踪:

[ODBC][26114][SQLPrepare.c][189]
                Entry:
                        Statement = 0x9e56060
                        SQL = [INSERT INTO blob_test(test) VALUES(?)][length = 37]
[ODBC][26114][SQLPrepare.c][364]
                Exit:[SQL_SUCCESS]
[ODBC][26114][SQLBindParameter.c][193]
                Entry:
                        Statement = 0x9e56060
                        Param Number = 1
                        Param Type = 1
                        C Type = -2 SQL_C_BINARY
                        SQL Type = -4 SQL_LONGVARBINARY
                        Col Def = 4096
                        Scale = 0
                        Rgb Value = 0xbfe9a990
                        Value Max = 0
                        StrLen Or Ind = 0xbfe9b99c
[ODBC][26114][SQLBindParameter.c][339]
                Exit:[SQL_SUCCESS]
[ODBC][26114][SQLExecute.c][183]
                Entry:
                        Statement = 0x9e56060
[ODBC][26114][SQLExecute.c][344]
                Exit:[SQL_NEED_DATA]
[ODBC][26114][SQLParamData.c][156]
                Entry:
                        Statement = 0x9e56060
                        Value = 0xbfe9a98c
[ODBC][26114][SQLParamData.c][327]
                Exit:[SQL_NEED_DATA]
                        Value = 0xbfe9a990
[ODBC][26114][SQLPutData.c][144]
                Entry:
                        Statement = 0x9e56060
                        Data = 0xbfe9a990
                        StrLen = 4096
[ODBC][26114][SQLPutData.c][289]
                Exit:[SQL_SUCCESS]
[ODBC][26114][SQLParamData.c][156]
                Entry:
                        Statement = 0x9e56060
                        Value = 0xbfe9a98c

在ESQL/C中,存储字节或文本blob的主机变量的数据类型是
loc\u t
,一种在标题中定义的结构类型,
“locator.h”
。我不是ODBC专家,但我希望您也需要与ODBC相同的结构。

请参阅:“IBM Informix ODBC驱动程序程序员手册”

不幸的是,我的要求是使用纯ODBC,而locator.h、loc\u t和SQL\u C\u BLOB\u locator类型似乎是特定于informix的。(至少我的测试应用程序无法使用它们,因为我的测试应用程序只能访问ODBC头)在这种情况下,您很可能处于一种“无需隐藏”的状态。我没有读过Informix ODBC手册,因此可能还有其他内容。但是驱动程序必须将您提供的任何内容转换为服务器期望的内容(这意味着定位器结构),但我不知道驱动程序是如何/在何处执行的。这并不是说这有助于解决问题,甚至不一定能证明什么,但我针对另一个ODBC驱动程序运行了您的确切代码,它工作得非常好。谢谢,我还成功地在MySQL上运行了它,所以我倾向于这是一个informix驱动程序问题。我可能不得不采取不同的方法和/或将其提交给IBM,以期得到修复或解决方案。
[ODBC][26114][SQLPrepare.c][189]
                Entry:
                        Statement = 0x9e56060
                        SQL = [INSERT INTO blob_test(test) VALUES(?)][length = 37]
[ODBC][26114][SQLPrepare.c][364]
                Exit:[SQL_SUCCESS]
[ODBC][26114][SQLBindParameter.c][193]
                Entry:
                        Statement = 0x9e56060
                        Param Number = 1
                        Param Type = 1
                        C Type = -2 SQL_C_BINARY
                        SQL Type = -4 SQL_LONGVARBINARY
                        Col Def = 4096
                        Scale = 0
                        Rgb Value = 0xbfe9a990
                        Value Max = 0
                        StrLen Or Ind = 0xbfe9b99c
[ODBC][26114][SQLBindParameter.c][339]
                Exit:[SQL_SUCCESS]
[ODBC][26114][SQLExecute.c][183]
                Entry:
                        Statement = 0x9e56060
[ODBC][26114][SQLExecute.c][344]
                Exit:[SQL_NEED_DATA]
[ODBC][26114][SQLParamData.c][156]
                Entry:
                        Statement = 0x9e56060
                        Value = 0xbfe9a98c
[ODBC][26114][SQLParamData.c][327]
                Exit:[SQL_NEED_DATA]
                        Value = 0xbfe9a990
[ODBC][26114][SQLPutData.c][144]
                Entry:
                        Statement = 0x9e56060
                        Data = 0xbfe9a990
                        StrLen = 4096
[ODBC][26114][SQLPutData.c][289]
                Exit:[SQL_SUCCESS]
[ODBC][26114][SQLParamData.c][156]
                Entry:
                        Statement = 0x9e56060
                        Value = 0xbfe9a98c