Hello,
I am seeing the following error from the SQL Server Driver For Linux when I attempt to execute a query on a SECOND connection within my application:
SQLSTATE: IM001
Native Error Code: 0
Message: [unixODBC][Driver Manager]Driver does not support this function
I have compiled/run the test case I have on Windows and the code executes without issue.
Here is my test case:
// SQLGetData.cpp
//
// g++ -M64 -I$ODBC/include -L$ODBC/lib -g -lodbc sqlgetdata.cpp
// cl sqlgetdata2.cpp odbc32.lib
//
// CREATE TABLE tstDFRBLB(col1 varbinary(max))
#if defined(_WIN32)
#include <windows.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
void checkError ( SQLRETURN rc, const char *cstr )
{
if( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO ) {
return ;
} else if( rc == SQL_INVALID_HANDLE ) {
fprintf( stderr, "Error: invalid handle: %s.\n", cstr ) ;
} else {
fprintf( stderr, "Unknown Error occured in %s: code %d.\n", cstr, rc ) ;
}
}
void checkStmtError( SQLRETURN rc, SQLHSTMT stmth )
{
if(rc != SQL_SUCCESS) {
int i = 1 ;
SQLSMALLINT length;
SQLINTEGER sqlcode;
SQLCHAR *sqlstate = (SQLCHAR *) malloc(100 * sizeof(SQLCHAR));
SQLCHAR *message = (SQLCHAR *) malloc(1000 * sizeof(SQLCHAR));
while ( SQLGetDiagRec( SQL_HANDLE_STMT, stmth, i, sqlstate, &sqlcode,
message, 1000, &length ) == SQL_SUCCESS ) {
printf( "\nSQLSTATE: %s\n", sqlstate ) ;
printf( "Native Error Code: %ld\n", sqlcode ) ;
printf( "Message: %s\n", message ) ;
i++ ;
}
delete sqlstate;
delete message;
}
}
int main( int ac, char **av )
{
SQLHENV envh ;
SQLHDBC dbch ;
SQLHDBC dbch2 ;
SQLRETURN rc ;
SQLHSTMT stmth ;
const char *select_stmt = "SELECT * FROM tstDFRBLB" ;
/* Allocate a environment handl */
rc = SQLAllocHandle( SQL_HANDLE_ENV, // Handle type
SQL_NULL_HANDLE, &envh // SQLHENV handle (environment)
) ;
checkError( rc, "SQLAllocHandle - SQL_HANDLE_ENV" ) ;
/* Set environment attributes */
rc = SQLSetEnvAttr( envh, // Environment handle
SQL_ATTR_ODBC_VERSION, // Attribute to set
(SQLPOINTER) SQL_OV_ODBC3,// New attribute
SQL_NTS // SQL_NTS (null terminated)
) ;
checkError( rc, "SQLSetEnvAttr" ) ;
/* Allocate a database connection handle */
rc = SQLAllocHandle( SQL_HANDLE_DBC, // Handle Type
envh, // Where to attatch the new handle
&dbch // Pointer to new handle
) ;
checkError( rc, "SQLAllocHandle - SQL_HANDLE_DBC" ) ;
/* Establish a connection */
SQLCHAR outStr[1024];
SQLSMALLINT outSize;
rc = SQLDriverConnect(dbch, NULL,
#if defined(_WIN32)
(SQLCHAR*)"DSN=MSSQL_2012_NC_64;UID=*****;PWD=*****;DATABASE=qe1;", 57,
#else
(SQLCHAR*)"DSN=mssql-2012-md_64;UID=*****;PWD=*****;DATABASE=qe1;", 57,
#endif
outStr, sizeof(outStr), &outSize, SQL_DRIVER_NOPROMPT);
/* Allocate a second database connection handle */
rc = SQLAllocHandle( SQL_HANDLE_DBC, // Handle Type
envh, // Where to attatch the new handle&dbch2 // Pointer to new handle
) ;
checkError( rc, "SQLAllocHandle - SQL_HANDLE_DBC" ) ;
rc = SQLSetConnectAttr(dbch2,
SQL_ODBC_CURSORS,
(SQLPOINTER)SQL_CUR_USE_DRIVER,
(SQLINTEGER)NULL); // this value is ignored
checkError( rc, "SQLSetConnectAttr - SQL_ODBC_CURSORS" ) ;
rc = SQLDriverConnect(dbch2, NULL,
#if defined(_WIN32)
(SQLCHAR*)"DSN=MSSQL_2012_NC_64;UID=*****;PWD=*****;DATABASE=qe1;", 57,
#else
(SQLCHAR*)"DSN=mssql-2012-md_64;UID=*****;PWD=*****;DATABASE=qe1;", 57,
#endif
outStr, sizeof(outStr), &outSize, SQL_DRIVER_NOPROMPT);
rc = SQLAllocHandle( SQL_HANDLE_STMT, dbch2, &stmth ) ;
checkError( rc, "SQLAllocHandle - SQL_HANDLE_STMT" ) ;
/*
** Read the value back
*/
rc = SQLExecDirect( stmth, (SQLCHAR*)select_stmt, SQL_NTS ) ;
checkStmtError( rc, stmth );
char outWData[168000];
SQLLEN outInd = 0;
while ( SQLFetch( stmth ) == SQL_SUCCESS )
{
rc = SQLGetData( stmth, 1, SQL_C_BINARY, outWData, sizeof(outWData), &outInd );
checkStmtError( rc, stmth );
if(outInd == SQL_NULL_DATA) {
printf("Data Returned: NULL\n");
}
else {
printf("Data Returned Length %d\n", outInd);
}
rc = SQLMoreResults(stmth);
checkStmtError( rc, stmth );
}
/* Disconnect from the database */
rc = SQLDisconnect( dbch2 ) ;
checkError( rc, "SQLDisconnect" ) ;
/* Free connection and environment handles */
rc = SQLFreeHandle( SQL_HANDLE_DBC, dbch2 ) ;
checkError( rc, "SQLDisconnect" ) ;
/* Disconnect from the database */
rc = SQLDisconnect( dbch ) ;
checkError( rc, "SQLDisconnect" ) ;
/* Free connection and environment handles */
rc = SQLFreeHandle( SQL_HANDLE_DBC, dbch ) ;
checkError( rc, "SQLDisconnect" ) ;
SQLFreeHandle( SQL_HANDLE_ENV, envh ) ;
checkError( rc, "SQLDisconnect" ) ;
return EXIT_SUCCESS ;
}
Thank you for any help/advice.
Dave
David Ritter