Subject | BUG? - "not yet implemented" from 2nd call to SQLParamData() ! |
---|---|
Author | JeffRobertsKy |
Post date | 2003-10-16T20:09:40Z |
I've got some code (it works with MySQL and SAP DB) that...
- calls SqlPrepare() for an INSERT statement with 3 parameters
- binds the first parameter directly to a buffer
- binds the second and third parameters, specifying SQL_DATA_AT_EXEC
- calls SqlExecute(), which returns SQL_NEED_DATA
- calls SqlParamData(), which fills in the address of the 2nd buffer
- calls SqlPutData() to send the data (just 4 bytes in one chunk)
- calls SqlParamData(), which returns -1. Using SQLGetDiagRec(), I
get an error string "not yet implemented".
I would expect to receive the address of the 3rd buffer when I make
the second call to SqlParamData(). The code is below...
=====================================================================
/**************** Lexmark Confidential ************************
* File: odbctest.cpp - test code for ddodbc
*
* Copyright (c) 2003 Lexmark International, Inc.
* All Rights Reserved
**************************************************************/
#include "stdafx.h"
int main(int argc,char* argv[])
{
SQLRETURN nResult;
SQLHENV hEnvHandle;
SQLHDBC hDBHandle;
SQLHSTMT hStmtHandle;
char szCmd[4096];
nResult = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
&hEnvHandle);
nResult = SQLSetEnvAttr(hEnvHandle, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
nResult = SQLAllocHandle(SQL_HANDLE_DBC, hEnvHandle, &hDBHandle);
SQLCHAR pMessage1[80];
SQLCHAR pMessage2[80];
SQLCHAR pMessage3[80];
memcpy(pMessage1, "foo", 3);pMessage1[3]= 0;
memcpy(pMessage2, "bar", 3);pMessage2[3]= 0;
memcpy(pMessage3, "bar", 3);pMessage3[3]= 0;
SQLUSMALLINT iParmNumber;
SQLSMALLINT iInOutType;
SQLSMALLINT iCDataType;
SQLSMALLINT iSQLDataType;
SQLUINTEGER iColumnSize;
SQLSMALLINT iDecimalDigits;
SQLPOINTER InBufferPointer;
SQLINTEGER InBufferLength;
long lexecvalue = SQL_DATA_AT_EXEC;
SQLINTEGER * LenBufferPointer;
char szConnect[2048];
//strcpy(szConnect, "DRIVER={XTG Systems InterBase6 ODBC
driver};SERVERNODE=localhost;SERVERDB=d:\\firebird\\lddserv.fdb;UID=s
ysdba;PWD=masterkey;OPTION=3");
strcpy(szConnect, "DRIVER=Firebird/Interbase(r)
driver;SERVERNODE=localhost;DBNAME=d:\\firebird\\lddserv.fdb;UID=sysd
ba;PWD=masterkey;OPTION=3");
SQLSMALLINT ConnInSize;
SQLUSMALLINT DriverCompInd;
SQLCHAR ConnOut[1500];
SQLSMALLINT ConnOutMaxSize;
SQLSMALLINT ConnOutSize;
SQLHWND WinHandle;
ConnInSize = strlen(szConnect);
DriverCompInd = SQL_DRIVER_NOPROMPT;
ConnOutSize = 0;
ConnOutMaxSize = 0;
WinHandle = NULL;
nResult = SQLDriverConnect(hDBHandle,
WinHandle,
(SQLCHAR*)szConnect,
ConnInSize,
ConnOut,
ConnOutMaxSize,
&ConnOutSize,
DriverCompInd);
// Drop old table in case we changed its structure since last run
nResult = SQLAllocHandle(SQL_HANDLE_STMT, hDBHandle,
&hStmtHandle);
strcpy(szCmd, "DROP TABLE TypeTable");
nResult = SQLExecDirect(hStmtHandle, (SQLCHAR *)(szCmd), SQL_NTS);
nResult = SQLFreeHandle(SQL_HANDLE_STMT, hStmtHandle);
// Create fresh table
nResult = SQLAllocHandle(SQL_HANDLE_STMT, hDBHandle,
&hStmtHandle);
//strcpy(szCmd, "CREATE TABLE TypeTable (TypeName VARCHAR(64) NOT
NULL, TypeInfo BLOB(80,1) NOT NULL, PRIMARY KEY (TypeName))");
//strcpy(szCmd, "CREATE TABLE TypeTable (TypeName VARCHAR(64) NOT
NULL, TypeInfo VARCHAR(32765) NOT NULL, PRIMARY KEY (TypeName))");
strcpy(szCmd, "CREATE TABLE TypeTable (TypeName VARCHAR(64) NOT
NULL, TypeInfo VARCHAR(64) NOT NULL, TypeInfo2 VARCHAR(32765) NOT
NULL, PRIMARY KEY (TypeName))");
nResult = SQLExecDirect(hStmtHandle, (SQLCHAR *)(szCmd), SQL_NTS);
nResult = SQLFreeHandle(SQL_HANDLE_STMT, hStmtHandle);
// Create the prepared insert
nResult = SQLAllocHandle(SQL_HANDLE_STMT, hDBHandle,
&hStmtHandle);
strcpy(szCmd, "INSERT INTO TypeTable (TypeName, TypeInfo,
TypeInfo2) VALUES (?, ?, ?)");
nResult = SQLPrepare(hStmtHandle, reinterpret_cast<unsigned char
*> (szCmd), SQL_NTS);
//////////////////////////////////////////////////////////////////
//////////////////////////
// Bind parameters
iParmNumber = 1;
iInOutType = SQL_PARAM_INPUT;
iCDataType = SQL_C_CHAR;
iSQLDataType = SQL_VARCHAR;
iColumnSize = 0;
iDecimalDigits = 0;
InBufferPointer = 0;
InBufferLength = sizeof(pMessage1);
LenBufferPointer = NULL;
//LenBufferPointer = &lexecvalue;
nResult = SQLBindParameter(hStmtHandle, iParmNumber, iInOutType,
iCDataType,
iSQLDataType, iColumnSize, iDecimalDigits, SQLPOINTER
(pMessage1),
InBufferLength, LenBufferPointer);
iParmNumber = 2;
iInOutType = SQL_PARAM_INPUT;
iCDataType = SQL_C_CHAR;
iSQLDataType = SQL_VARCHAR;
iColumnSize = 0;
iDecimalDigits = 0;
InBufferPointer = 0;
InBufferLength = sizeof(pMessage2);
//LenBufferPointer = NULL;
LenBufferPointer = &lexecvalue;
nResult = SQLBindParameter(hStmtHandle, iParmNumber, iInOutType,
iCDataType,
iSQLDataType, iColumnSize,
iDecimalDigits, SQLPOINTER (pMessage2),
InBufferLength, LenBufferPointer);
iParmNumber = 3;
iInOutType = SQL_PARAM_INPUT;
iCDataType = SQL_C_CHAR;
iSQLDataType = SQL_VARCHAR;
iColumnSize = 0;
iDecimalDigits = 0;
InBufferPointer = 0;
InBufferLength = sizeof(pMessage3);
//LenBufferPointer = NULL;
LenBufferPointer = &lexecvalue;
nResult = SQLBindParameter(hStmtHandle, iParmNumber, iInOutType,
iCDataType,
iSQLDataType, iColumnSize,
iDecimalDigits, SQLPOINTER (pMessage3),
InBufferLength, LenBufferPointer);
//////////////////////////////////////////////////////////////////
//////////////////////////
// Execute the prepared statement
nResult = SQLExecute(hStmtHandle);
SQLPOINTER pParmAddress=NULL; // an address of a parameter
bool bParms = true;
if (nResult == SQL_NEED_DATA)
{
while (bParms)
{
// long data is requested by the driver must send data in
parts
// see which data element the driver requires and send data
until finished
nResult = SQLParamData(hStmtHandle, (SQLPOINTER *)
&pParmAddress);
#if 1
SQLCHAR sscSQLState[6];
SQLINTEGER siNativeError;
char szError[4096];
SQLSMALLINT ssiTextLength;
SQLGetDiagRec(SQL_HANDLE_STMT,hStmtHandle,(SQLSMALLINT)
1,sscSQLState,&siNativeError,(SQLCHAR*)szError,4096,&ssiTextLength);
#endif
if (nResult == SQL_NEED_DATA)
{
nResult = SQLPutData(hStmtHandle, (SQLPOINTER)
pParmAddress, 4);
((LPTSTR)pParmAddress)[0] = '\0';
}
else
{
bParms = false;
}
} // end while (bParms)
}
nResult = SQLFreeHandle(SQL_HANDLE_STMT, hStmtHandle);
return(0);
}
- calls SqlPrepare() for an INSERT statement with 3 parameters
- binds the first parameter directly to a buffer
- binds the second and third parameters, specifying SQL_DATA_AT_EXEC
- calls SqlExecute(), which returns SQL_NEED_DATA
- calls SqlParamData(), which fills in the address of the 2nd buffer
- calls SqlPutData() to send the data (just 4 bytes in one chunk)
- calls SqlParamData(), which returns -1. Using SQLGetDiagRec(), I
get an error string "not yet implemented".
I would expect to receive the address of the 3rd buffer when I make
the second call to SqlParamData(). The code is below...
=====================================================================
/**************** Lexmark Confidential ************************
* File: odbctest.cpp - test code for ddodbc
*
* Copyright (c) 2003 Lexmark International, Inc.
* All Rights Reserved
**************************************************************/
#include "stdafx.h"
int main(int argc,char* argv[])
{
SQLRETURN nResult;
SQLHENV hEnvHandle;
SQLHDBC hDBHandle;
SQLHSTMT hStmtHandle;
char szCmd[4096];
nResult = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
&hEnvHandle);
nResult = SQLSetEnvAttr(hEnvHandle, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
nResult = SQLAllocHandle(SQL_HANDLE_DBC, hEnvHandle, &hDBHandle);
SQLCHAR pMessage1[80];
SQLCHAR pMessage2[80];
SQLCHAR pMessage3[80];
memcpy(pMessage1, "foo", 3);pMessage1[3]= 0;
memcpy(pMessage2, "bar", 3);pMessage2[3]= 0;
memcpy(pMessage3, "bar", 3);pMessage3[3]= 0;
SQLUSMALLINT iParmNumber;
SQLSMALLINT iInOutType;
SQLSMALLINT iCDataType;
SQLSMALLINT iSQLDataType;
SQLUINTEGER iColumnSize;
SQLSMALLINT iDecimalDigits;
SQLPOINTER InBufferPointer;
SQLINTEGER InBufferLength;
long lexecvalue = SQL_DATA_AT_EXEC;
SQLINTEGER * LenBufferPointer;
char szConnect[2048];
//strcpy(szConnect, "DRIVER={XTG Systems InterBase6 ODBC
driver};SERVERNODE=localhost;SERVERDB=d:\\firebird\\lddserv.fdb;UID=s
ysdba;PWD=masterkey;OPTION=3");
strcpy(szConnect, "DRIVER=Firebird/Interbase(r)
driver;SERVERNODE=localhost;DBNAME=d:\\firebird\\lddserv.fdb;UID=sysd
ba;PWD=masterkey;OPTION=3");
SQLSMALLINT ConnInSize;
SQLUSMALLINT DriverCompInd;
SQLCHAR ConnOut[1500];
SQLSMALLINT ConnOutMaxSize;
SQLSMALLINT ConnOutSize;
SQLHWND WinHandle;
ConnInSize = strlen(szConnect);
DriverCompInd = SQL_DRIVER_NOPROMPT;
ConnOutSize = 0;
ConnOutMaxSize = 0;
WinHandle = NULL;
nResult = SQLDriverConnect(hDBHandle,
WinHandle,
(SQLCHAR*)szConnect,
ConnInSize,
ConnOut,
ConnOutMaxSize,
&ConnOutSize,
DriverCompInd);
// Drop old table in case we changed its structure since last run
nResult = SQLAllocHandle(SQL_HANDLE_STMT, hDBHandle,
&hStmtHandle);
strcpy(szCmd, "DROP TABLE TypeTable");
nResult = SQLExecDirect(hStmtHandle, (SQLCHAR *)(szCmd), SQL_NTS);
nResult = SQLFreeHandle(SQL_HANDLE_STMT, hStmtHandle);
// Create fresh table
nResult = SQLAllocHandle(SQL_HANDLE_STMT, hDBHandle,
&hStmtHandle);
//strcpy(szCmd, "CREATE TABLE TypeTable (TypeName VARCHAR(64) NOT
NULL, TypeInfo BLOB(80,1) NOT NULL, PRIMARY KEY (TypeName))");
//strcpy(szCmd, "CREATE TABLE TypeTable (TypeName VARCHAR(64) NOT
NULL, TypeInfo VARCHAR(32765) NOT NULL, PRIMARY KEY (TypeName))");
strcpy(szCmd, "CREATE TABLE TypeTable (TypeName VARCHAR(64) NOT
NULL, TypeInfo VARCHAR(64) NOT NULL, TypeInfo2 VARCHAR(32765) NOT
NULL, PRIMARY KEY (TypeName))");
nResult = SQLExecDirect(hStmtHandle, (SQLCHAR *)(szCmd), SQL_NTS);
nResult = SQLFreeHandle(SQL_HANDLE_STMT, hStmtHandle);
// Create the prepared insert
nResult = SQLAllocHandle(SQL_HANDLE_STMT, hDBHandle,
&hStmtHandle);
strcpy(szCmd, "INSERT INTO TypeTable (TypeName, TypeInfo,
TypeInfo2) VALUES (?, ?, ?)");
nResult = SQLPrepare(hStmtHandle, reinterpret_cast<unsigned char
*> (szCmd), SQL_NTS);
//////////////////////////////////////////////////////////////////
//////////////////////////
// Bind parameters
iParmNumber = 1;
iInOutType = SQL_PARAM_INPUT;
iCDataType = SQL_C_CHAR;
iSQLDataType = SQL_VARCHAR;
iColumnSize = 0;
iDecimalDigits = 0;
InBufferPointer = 0;
InBufferLength = sizeof(pMessage1);
LenBufferPointer = NULL;
//LenBufferPointer = &lexecvalue;
nResult = SQLBindParameter(hStmtHandle, iParmNumber, iInOutType,
iCDataType,
iSQLDataType, iColumnSize, iDecimalDigits, SQLPOINTER
(pMessage1),
InBufferLength, LenBufferPointer);
iParmNumber = 2;
iInOutType = SQL_PARAM_INPUT;
iCDataType = SQL_C_CHAR;
iSQLDataType = SQL_VARCHAR;
iColumnSize = 0;
iDecimalDigits = 0;
InBufferPointer = 0;
InBufferLength = sizeof(pMessage2);
//LenBufferPointer = NULL;
LenBufferPointer = &lexecvalue;
nResult = SQLBindParameter(hStmtHandle, iParmNumber, iInOutType,
iCDataType,
iSQLDataType, iColumnSize,
iDecimalDigits, SQLPOINTER (pMessage2),
InBufferLength, LenBufferPointer);
iParmNumber = 3;
iInOutType = SQL_PARAM_INPUT;
iCDataType = SQL_C_CHAR;
iSQLDataType = SQL_VARCHAR;
iColumnSize = 0;
iDecimalDigits = 0;
InBufferPointer = 0;
InBufferLength = sizeof(pMessage3);
//LenBufferPointer = NULL;
LenBufferPointer = &lexecvalue;
nResult = SQLBindParameter(hStmtHandle, iParmNumber, iInOutType,
iCDataType,
iSQLDataType, iColumnSize,
iDecimalDigits, SQLPOINTER (pMessage3),
InBufferLength, LenBufferPointer);
//////////////////////////////////////////////////////////////////
//////////////////////////
// Execute the prepared statement
nResult = SQLExecute(hStmtHandle);
SQLPOINTER pParmAddress=NULL; // an address of a parameter
bool bParms = true;
if (nResult == SQL_NEED_DATA)
{
while (bParms)
{
// long data is requested by the driver must send data in
parts
// see which data element the driver requires and send data
until finished
nResult = SQLParamData(hStmtHandle, (SQLPOINTER *)
&pParmAddress);
#if 1
SQLCHAR sscSQLState[6];
SQLINTEGER siNativeError;
char szError[4096];
SQLSMALLINT ssiTextLength;
SQLGetDiagRec(SQL_HANDLE_STMT,hStmtHandle,(SQLSMALLINT)
1,sscSQLState,&siNativeError,(SQLCHAR*)szError,4096,&ssiTextLength);
#endif
if (nResult == SQL_NEED_DATA)
{
nResult = SQLPutData(hStmtHandle, (SQLPOINTER)
pParmAddress, 4);
((LPTSTR)pParmAddress)[0] = '\0';
}
else
{
bParms = false;
}
} // end while (bParms)
}
nResult = SQLFreeHandle(SQL_HANDLE_STMT, hStmtHandle);
return(0);
}