freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
- From: "Ken Bradley" <bradleyk AT mentorgen.com>
- To: freetds AT franklin.oit.unc.edu
- Subject: SQLServer 2000, SQLBindCol, res_info=NULL
- Date: Wed, 15 May 2002 14:54:08 -0400
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
- SQLServer 2000, SQLBindCol, res_info=NULL, Ken Bradley, 05/15/2002
Archive powered by MHonArc 2.6.24.