SQLServer 2000, SQLBindCol, res_info=NULL

Ken Bradley bradleyk at mentorgen.com
Wed May 15 15:54:08 EDT 2002


I using FreeTDS 0.53 and unixODBC 2.2.1 to access a SQLServer 2000
database.  From the command line, using isql, everything seems to work
fine.  I can do a select * from <table_name>, and I get the expected result.  If I try
the same "select" from a C program, using SQLBindCol, the program seg
faults.  I have run it through gdb and have found that in odbc.c, line 504
(colinfo = tds->res_info->columns[icol-1]), tds->res_info is NULL.  Also
(if I comment the SQLBindCol's out) SQLRowCount, returns 0 rows, but if I
do a SQLFetch, it will return 3 rows (which is correct, but of course I
get no data, since I can't bind any variable to the columns ;)  I am able
to reproduced this on both Redhat 7.0 and Solaris 8.  I have included my
sample program, which is pretty much the sample program on the unixODBC
site, as well as my freetds.conf, odbcinst.ini and odbc.ini.  I have also
tried both 7.0 and 4.2 for the version as well as the big_endian vs.
little_endian stuff, same results everytime.  How is res_info supposed to
get set, and with what?  Is this potentially something on the SQLServer
2000 that isn't getting set correctly?

Thanks,
-Ken






#include <stdlib.h>
#include <stdio.h>
#include <odbc/sql.h>
#include <odbc/sqlext.h>
#include <odbc/sqltypes.h>

int main(int argc,char *argv[])
{
SQLHENV                  V_OD_Env;     // Handle ODBC environment
long                     V_OD_erg;     // result of functions
SQLHDBC                  V_OD_hdbc;    // Handle connection
SQLHSTMT                 V_OD_hstmt;    // Handle connection

char                     V_OD_stat[10]; // Status SQL
SQLLEN           V_OD_err,V_OD_rowanz,V_OD_id;
SQLSMALLINT              V_OD_mlen, V_OD_colanz;
char             V_OD_msg[200];
SQLCHAR                     source[200], OID[200], reason[200],
stuff[4000];
SQL_TIMESTAMP_STRUCT        timeStamp;

         SQLSMALLINT nameLength, dataType, decDigits, nullPtr;
         SQLUINTEGER  colSize;
         int i;
        // 1. allocate Environment handle and register version
        V_OD_erg=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
        if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg !=
SQL_SUCCESS_WITH_INFO))
        {
                printf("Error AllocHandle\n");
                exit(0);
        }
        V_OD_erg=SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION,
                               (void*)SQL_OV_ODBC3, 0);
        if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg !=
SQL_SUCCESS_WITH_INFO))
        {
                printf("Error SetEnv\n");
                SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
                exit(0);
        }
        // 2. allocate connection handle, set timeout
        V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
        if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg !=
SQL_SUCCESS_WITH_INFO))
        {
                printf("Error AllocHDB %d\n",V_OD_erg);
                SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
                exit(0);
        }
        SQLSetConnectAttr(V_OD_hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5,
0);
        // 3. Connect to the datasource "web"
        V_OD_erg = SQLConnect(V_OD_hdbc, "OSSM", SQL_NTS,
                                     "Ems", SQL_NTS,
                                     "ems", SQL_NTS);
        if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg !=
SQL_SUCCESS_WITH_INFO))
        {
                printf("Error SQLConnect %d\n",V_OD_erg);
                SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, (SQLCHAR
*)V_OD_stat, &V_OD_err,(SQLCHAR *)V_OD_msg,100,&V_OD_mlen);
                printf("%s (%d)\n",V_OD_msg,V_OD_err);
                SQLFreeHandle(SQL_HANDLE_DBC, V_OD_hdbc);
                SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
                exit(0);
        }
        printf("%s,\n", "SQL Connected");
        /* continued on next page */
        V_OD_erg=SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
        if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg !=
SQL_SUCCESS_WITH_INFO))
        {
                printf("Fehler im AllocStatement %d\n",V_OD_erg);
                SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, (SQLCHAR
*)V_OD_stat,&V_OD_err,(SQLCHAR *)V_OD_msg,100,&V_OD_mlen);
                printf("%s (%d)\n",V_OD_msg,V_OD_err);
        SQLDisconnect(V_OD_hdbc);
        SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
                SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
                exit(0);
        }


    SQLBindCol(V_OD_hstmt,1,SQL_C_TYPE_TIMESTAMP,
&timeStamp,150,&V_OD_err);
    SQLBindCol(V_OD_hstmt,2,SQL_C_CHAR, &source,150,&V_OD_err);
    SQLBindCol(V_OD_hstmt,3,SQL_C_CHAR,&OID,150,&V_OD_err);
    SQLBindCol(V_OD_hstmt,4,SQL_C_CHAR,&reason,150,&V_OD_err);
    SQLBindCol(V_OD_hstmt,5,SQL_C_CHAR,&stuff,2000,&V_OD_err);




    V_OD_erg=SQLExecDirect(V_OD_hstmt,(SQLCHAR *)"SELECT * FROM
snmp_header",SQL_NTS);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
       printf("Error in Select %d\n",V_OD_erg);
       SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, (SQLCHAR
*)V_OD_stat,&V_OD_err,(SQLCHAR *)V_OD_msg,100,&V_OD_mlen);
       printf("%s (%d)\n",V_OD_msg,V_OD_err);
       SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
       SQLDisconnect(V_OD_hdbc);
       SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
       SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
       exit(0);
    }

    V_OD_erg=SQLNumResultCols(V_OD_hstmt,&V_OD_colanz);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
        SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
        SQLDisconnect(V_OD_hdbc);
        SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
        SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
        exit(0);
    }
    for (i = 1; i <= V_OD_colanz; i++) {
    SQLDescribeCol(V_OD_hstmt, i, stuff, 1000, &nameLength, &dataType,
&colSize, &decDigits, &nullPtr);
   printf("%s %d %d %d %d %d \n", stuff, nameLength, dataType, colSize,
decDigits, nullPtr);
}
    printf("Number of Columns %d\n",V_OD_colanz);
    V_OD_erg=SQLRowCount(V_OD_hstmt,&V_OD_rowanz);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
      printf("Number ofRowCount %d\n",V_OD_erg);
      SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
      SQLDisconnect(V_OD_hdbc);
      SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
      SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
      exit(0);
    }
    printf("Number of Rows %d\n",V_OD_rowanz);

    V_OD_erg=SQLFetch(V_OD_hstmt);
    while(V_OD_erg != SQL_NO_DATA)
    {
     printf("Result: %s \n",source);
     V_OD_erg=SQLFetch(V_OD_hstmt);
    }  ;

    SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
    SQLDisconnect(V_OD_hdbc);
    SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
    SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
    return(0);
}





freetds.conf


# Global settings, any value here may be overridden by a database
# server specific section
[global]
        # TDS protocol version
        tds version = 4.2

        initial block size = 512

        swap broken dates = no

        swap broken money = no

        # Database server login method, if both server and domain
        # logins are enabled, domain login is tried first if a domain
        # is specified, and if that fails the server login will be used.
        try server login = yes
        try domain login = no

        # The default authentication domain, can be overridden by
        # specifying a username with a domain prefix, e.g. DOMAIN\username
;       nt domain = WORKGROUP

        # If the server responds with different domain try that one?
        cross domain login = no

        # Whether to write a TDSDUMP file for diagnostic purposes
        # (setting this to /tmp is insecure on a multi-user system)
;       dump file = /tmp/freetds.log
;       debug level = 10

        # Command and connection timeouts
;       timeout = 10;
;       connect timeout = 10;

[OSSM]
        host = 192.168.1.82
        port = 1433
        tds version = 4.2
        emulate little endian = yes




odbcinst.ini

[TDS]
Description             = TDS v0.53
Driver          = /usr/local/freetds/lib/libtdsodbc.so





.odbc.ini

[OSSM]
Driver          = /usr/local/freetds/lib/libtdsodbc.so
Description             = Mentorgen OSSM Database
Trace           = No
Servername              = 192.168.1.82
Database                = EMS
UID             = Ems













More information about the FreeTDS mailing list