2016-11-15 6 views
0

는 시나리오 리눅스 플랫폼에서 bytea와 열이 옥텟에 인쇄 가능한 문자를 변환 : 내가 데이터베이스에서 blobdata 열을 쿼리 할 때PostgreSQL 데이터베이스 여기

CREATE TABLE amaaa 
(
    laaaid integer NOT NULL DEFAULT 0, 
    blobdata bytea 
) 
INSERT INTO amaaa(laaaid)VALUES (1); 
SQLRETURN connect() 
{ 
    SQLRETURN ret; /* ODBC API return status */ 

    /* Allocate an environment handle */ 
    ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &myestenv); 

    /* We want ODBC 3 support */ 
    if (!ret) ret = SQLSetEnvAttr(myestenv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); 

    /* Allocate a connection handle */ 
    if (!ret) ret = SQLAllocHandle(SQL_HANDLE_DBC, myestenv, &dbc); 

    SQLSetConnectOption(dbc, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON); 
    const char* connectStr = "ByteaAsLongVarBinary=1;LFConversion=0;DSN=AMPG961;UID=postgres;PWD={postgres}"; 
    if (!ret) ret = SQLDriverConnect(dbc, NULL, (SQLCHAR*)connectStr, strlen(connectStr), NULL, 0, NULL, SQL_DRIVER_NOPROMPT); 

    /* Allocate a statement handle */ 
    if (!ret) ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); 

    if (ret) getErr(ret); 

    return ret; 
} 

void disconnect() 
{ 
    /* Disconnect and free all the handles */ 
    SQLRETURN ret = SQLFreeHandle(SQL_HANDLE_STMT, stmt); 
    ret = SQLDisconnect(dbc); 
    ret = SQLFreeHandle(SQL_HANDLE_DBC, dbc); 
    ret = SQLFreeHandle(SQL_HANDLE_ENV, myestenv); 
} 

const USHORT LEN = 3; 
SQLRETURN update() 
{ 
    SQLRETURN ret = connect(); 
    if (ret) return ret; 

    const unsigned char vLob[LEN] = "v="; 
    long lBlobLen = LEN - 1; 
    int lMainRecordId = 1; 

    SQLLEN cbValue = lBlobLen; 

    ret = SQLPrepare(stmt, (SQLCHAR*)"UPDATE \"amaaa\" set blobdata = ? where laaaid = ?;", SQL_NTS); 

    if (!ret) ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, 
     SQL_BINARY, SQL_LONGVARBINARY, 0, 
    0, (void*)vLob, lBlobLen, &cbValue); 

    SQLLEN cbLen = 4; 

    ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, 
         SQL_C_LONG, SQL_INTEGER, 0, 
         0, (void*)&lMainRecordId, sizeof(long), &cbLen); 

    if (!ret) ret = SQLExecute(stmt); 
    if ((ret != SQL_SUCCESS) && (ret != SQL_NEED_DATA) && (ret != SQL_SUCCESS_WITH_INFO)) { 
    printf("SQLExecDirect Failed\n\n"); 
    getErr(ret); 
    disconnect(); 
    } 
    return ret; 
} 

, 값은 항상, 사실은 내가 값을 '075 \ v에' 내가 입력 한 것은 'v ='; 하지만 Windows 플랫폼에서는 동일한 코드가 문제가되지 않습니다. 그것에 대해 궁금하십니까?

미리 감사드립니다.

+0

질문이 명확하지 않습니다. 테이블에 아무 것도 삽입되지 않으므로 비어 있어야합니다. 이 질의를 갖는'odbc' 태그,'C++'보다는 abd'c'가 있어야합니다. –

+0

조언 해 주셔서 감사합니다. – Ramin

답변

0

모든 것이 잘되는 것처럼 보입니다. 데이터베이스에 저장

바이트는 118, 61, 또는 0x76 16 진수 및 0x3D, 또는 진수 0166 및 075.

가 정확히 두 바이트가 bytea 열에 저장된 얻을이다 v=에 대한 ASCII 값입니다 !

명백한 문제는 데이터베이스를 쿼리하는 데 사용하는 도구 때문입니다.
ASCII 문자에 해당하는 모든 바이트를 해당 문자로 표시하고 다른 모든 바이트는 세 자리의 8 진수 (백 슬래시 앞에 있음)로 표시합니다.
값이 v\075 인 이유입니다.

0

문제는 CentOS RPM에서 최신 인 psqlODBC 9.03을 사용하는 CentOS 7.2에서 재생할 수 있습니다.

psqlODBC 버전을 9.03에서 9.05로 업그레이드하면이 문제가 해결됩니다.

psqlODBC 9.05는 CentOS에서 직접 컴파일되었습니다.

다른 사용자에게 도움이되기를 바랍니다.