I'm trying to use on PostgreSQL 12.2 an updatable cursor inside transaction using the ODBC driver (ANSI 12.1) and C++.
If I declare the cursor with SQLSetCursorName and SQLPrepare + SQLExecute for the query in one statement, and the update in other statement it gives the SQLSTATE 24000 and message cursor "cur0" is not positioned on a row.
If the update is made in the same statement, it gives the SQLSTATE 24000 and message Invalid cursor state.
On the DSN I've checked Use Declare/Fetch, set the Level of rollback on errors option to Statement, and unchecked Updatable Cursors, following what is in https://www.microfocus.com/documentation/enterprise-developer/ed40pu15/ED-VS2015/GUID-1F1C4505-B771-4F8E-B274-952CAF3E8265.html.
The only way possible was with SQLSetPos, but using the same statement for the SELECT and the UPDATE, as described in http://micronetinternational.com/index.pl/en/00/https/www.postgresql-archive.org/ERROR-with-quot-Update-where-Current-of-quot-td4499184.html.
Using DBeaver, which uses a JDBC driver, it works normally.
Is it possible to make the update with a different update statement on PostgreSQL using the ODBC driver?
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
check_rc(henv, hdbc, hstmt, rc);
rc = lpfSqlConnect(hdbc, (SQLCHAR*)"mydsn", SQL_NTS, (SQLCHAR*)"user", SQL_NTS, (SQLCHAR*)"pass", SQL_NTS);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_NOSCAN, (SQLPOINTER)SQL_NOSCAN_ON, SQL_IS_INTEGER);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (void *)SQL_CURSOR_KEYSET_DRIVEN, 0);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_ROWVER, 0);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLSetCursorName(hstmt, (SQLCHAR *)"cur0", SQL_NTS);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLPrepare(hstmt, (SQLCHAR *)"select field1, field2 from mytable", SQL_NTS);
check_rc(henv, hdbc, hstmt, rc);
rc = SQLExecute(hstmt);
check_rc(henv, hdbc, hstmt, rc);
SQLSMALLINT iNumCols = 0;
rc = SQLNumResultCols(hstmt, &iNumCols);
check_rc(henv, hdbc, hstmt, rc);
for(i = 0; i < iNumCols; ++i)
{
rc = SQLBindCol(hstmt, i + 1, SQL_C_CHAR, data[i], collen[i], &outlen[i]);
check_rc(henv, hdbc, hstmt, rc);
}
for (i = 0; i < 4; ++i)
{
rc = SQLFetch(hstmt);
check_rc(henv, hdbc, hstmt, rc);
}
//////////////////////////////////////////////////////////////////
//it returns SQL_ERROR, SQLSTATE=24000, message "[Microsoft][ODBC Driver Manager] Invalid cursor state"
rc = SQLExecDirect(hstmt, (SQLCHAR *)"UPDATE mytable SET field3 = 'newvalue' where current of cur0", SQL_NTS);
check_rc(henv, hdbc, hstmt, rc);
/////////////////////////////////////////////////////////////////
//or
SQLHSTMT hstmt2 = SQL_NULL_HSTMT; // Statement Handle
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt2);
check_rc(henv, hdbc, hstmt2, rc);
rc = SQLSetStmtAttr(hstmt2, SQL_ATTR_RETRIEVE_DATA, (SQLPOINTER)SQL_RD_OFF, SQL_IS_INTEGER);
check_rc(henv, hdbc, hstmt2, rc);
//it returns SQL_ERROR, SQLSTATE=24000, message ERROR: cursor "cur0" is not positioned on a row;
rc = SQLExecDirect(hstmt2, (SQLCHAR *)"UPDATE mytable SET field3 = 'newvalue' where current of cur0", SQL_NTS);
check_rc(henv, hdbc, hstmt2, rc);
////////////////////////////////////////////////////////////
rc = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
check_rc(henv, hdbc, NULL, rc);
rc = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);
check_rc(henv, hdbc, hstmt, rc);
Related
I have been trying to insert a row into my SQL table, i get no syntax error but unfortunately when i check my table in the SQL Server Management Studio, no new entry is added. When debugging, the retCode becomes less than zero starting from the SQLConnect() function.
int main()
{
SQLHANDLE SQLEnvHandle = NULL;
SQLHANDLE SQLConnectionHandle = NULL;
SQLHANDLE SQLStatementHandle = NULL;
SQLRETURN retCode = 0;
// Insert Query
char SQLQuery[] = "insert into crm.dbo.company_name values (22,'01 electronics','#01electronics.net');";
// SQL Server Identifier
char SQLServer[] = "DRIVER={SQL Server}; SERVER=localhost, 8000; DATABASE=xxxx; UID=xxxx_xxxx; PWD=xxxx;";
do
{
// Allocate environment
retCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &SQLEnvHandle);
// Set ODBC Version
retCode = SQLSetEnvAttr(SQLEnvHandle, SQL_ATTR_ODBC_VERSION,(SQLPOINTER*)SQL_OV_ODBC3, 0);
// Allocate Connection
retCode = SQLAllocHandle(SQL_HANDLE_DBC, SQLEnvHandle, &SQLConnectionHandle);
// Set Login Timeout
retCode = SQLSetConnectAttr(SQLConnectionHandle, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
// Set Auto Commit
retCode = SQLSetConnectAttr(SQLConnectionHandle, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)TRUE, 0);
// Connect to DSN
retCode = SQLConnect(SQLConnectionHandle, (SQLCHAR*) SQLServer, SQL_NTS, (SQLCHAR*)NULL, 0, NULL, 0);
// Allocate Statement Handle
retCode = SQLAllocHandle(SQL_HANDLE_STMT, SQLConnectionHandle, &SQLStatementHandle);
// Prepare Statement
retCode = SQLPrepare(SQLStatementHandle, (SQLCHAR*)SQLQuery, SQL_NTS);
// Execute Statement
if (SQLExecute(SQLStatementHandle) == SQL_SUCCESS || SQLExecute(SQLStatementHandle) == SQL_SUCCESS_WITH_INFO)
cout << "SUCCESS";
else
cout << "FAILURE";
} while (FALSE);
// Frees the resources and disconnects
SQLFreeHandle(SQL_HANDLE_STMT, SQLStatementHandle);
SQLDisconnect(SQLConnectionHandle);
SQLFreeHandle(SQL_HANDLE_DBC, SQLConnectionHandle);
SQLFreeHandle(SQL_HANDLE_ENV, SQLEnvHandle);
getchar();
}
When debugging, the retCode becomes less than zero starting from the SQLConnect() function.
From the docs:
When SQLConnect returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an
associated SQLSTATE value can be obtained by calling SQLGetDiagRec
with a HandleType of SQL_HANDLE_DBC and a Handle of ConnectionHandle
I have the following code (using ODBC to connect to an SQL database):
The connection is OK and also the first SQL_ExecuteQuery(), but the second and third SQL_ExecuteQuery() will return with an error (returncode -1 for SQLExecDirect).
I assume, that the "statement handle hstmt" will be overwritten after the first execution. But how can I avoid this? Thank you so much.
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc = SQL_NULL_HDBC;
SQLHDBC hstmt= SQL_NULL_HSTMT;
SQLRETURN retcode = SQL_SUCCESS;
//Connect function
int SQL_Connect()
{
SQLWCHAR OutConnStr[255];
SQLSMALLINT OutConnStrLen;
// Allocate environment handle
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// Set the ODBC version environment attribute
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
// Allocate connection handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// Set login timeout to 5 seconds
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
retcode = SQLDriverConnect( hdbc,
NULL,
#ifdef IPC
(SQLWCHAR *)L"DSN=TEST;Description=ODK;UID=FFF;PWD=XXX;Trusted_Connection=No;DATABASE=DDD;",
#else
(SQLWCHAR *)L"DSN=ODKSQL64;Description=ODK;UID=auto;PWD=Visu_KDbos;Trusted_Connection=No;DATABASE=Giesserei_BKO;",
#endif
SQL_NTS,
OutConnStr,
255,
&OutConnStrLen,
SQL_DRIVER_NOPROMPT);
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
cout<<"Verbindung OK"<<std::endl;
}
}
}
}
return retcode;
}
//Disonnect function
int SQL_Disconnect ()
{
SQLFreeHandle(SQL_HANDLE_STMT, hstmt );
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 1;
}
//Query function
int SQL_ExecuteQuery()
{
short rc;
char material[50];
SQLINTEGER strlenmaterial;
//prepare query
std::wstring SQL_Statement = L"SELECT blablabla";
rc = SQLExecDirect(hstmt, const_cast<SQLWCHAR*>(SQL_Statement.c_str()), SQL_NTS);
if (rc==SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO) {
SQLBindCol(hstmt, 1, SQL_C_CHAR, &material, (SQLINTEGER) sizeof(material), &strlenmaterial);
while (1) {
rc = SQLFetch(hstmt);
if (rc==SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO) {
rc = 1;
}else {
break;
}
}
} else {
//no data found
rc = 3;
}
return rc;
}
int main()
{
short rc;
rc = SQL_Connect();
rc = SQL_ExecuteQuery();
rc = SQL_ExecuteQuery();
rc = SQL_ExecuteQuery();
rc = SQL_Disconnect();
return 0;
}
You can re-use a HSTMT handle, but before running a new query, you need to close the pending cursor. As you are binding the columns using SQLBindCol, you also need to unbind the columns, before binding them again.
In your SQL_ExecuteQuery(), before returning from the function call:
SQLFreeStmt(hstmt, SQL_UNBIND)
SQLFreeStmt(hstmt, SQL_CLOSE)
Now you are ready to execute another query, bind again and fetch the result.
Note that you could also change the logic of your program, and bind only once, and then skip the unbind-step: If you know that you are always interested in the result of the same column, you could bind the column before executing the query. You can then execute the query, read the result, call SQLFreeStmt with the SQL_CLOSE option and start over with executing the query.
See here for more details:
https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfreestmt-function
I am trying to read a large object from a PostgreSQL database using ODBC from Visual Studio C++. I can't get it to work.
The driver is PostgresSQL ANSI(x64) 9.50.04.00.
The data type of the column is lo, created with:
CREATE DOMAIN lo AS oid;
The column contains the object ids of the large objects.
My understanding is that when the driver sees a lo type, it will handle it as SQL_LONGVARBINARY.
However, the query fails. The diagnostics message is:
HY003 [Microsoft][OBDC Driver Manager] Program type out of range
Here is the code with the noise removed:
wchar_t* connect0 = L"DSN=picdb;";
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLLEN sqllen = -1;
PBYTE image = new BYTE[0];
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
SQLDriverConnect(dbc, NULL, connect0, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
SQLExecDirect(stmt, L"select lo from image_list where id=964945", SQL_NTS);
SQLFetch(stmt);
SQLGetData(stmt, 1, SQL_LONGVARBINARY, image, 0, &sqllen); //<----- It fails here
image = new BYTE[sqllen];
SQLGetData(stmt, 1, SQL_LONGVARBINARY, image, sqllen, &sqllen);
SQLDisconnect(dbc);
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
I can read regular data from the database just fine. And I can read the BLOB data from the database with Java/JDBC, but I need it to work in C++.
Why do I get the error, and what can I do to fix it?
This seems to work:
wchar_t* connect0 = L"DSN=picdb;";
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLLEN sqllen = -1;
PBYTE image = new BYTE[0];
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
SQLDriverConnect(dbc, NULL, connect0, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
SQLExecDirect(stmt, L"select lo from image_list where id=964945", SQL_NTS);
SQLFetch(stmt);
SQLGetData(stmt, 1, SQL_C_BINARY, image, 0, &sqllen);
image = new BYTE[sqllen];
SQLBindParameter(stmt, 1, SQL_PARAM_OUTPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, image, sqllen, NULL );
SQLGetData(stmt, 1, SQL_C_BINARY, image, sqllen, &sqllen);
SQLDisconnect(dbc);
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
I am trying to run following stored procedure using ODBC:
CREATE PROCEDURE [dbo].[Add]
--WITH ENCRYPTION
AS
DECLARE #LoopVar BIGINT = 0
, #MaxVar BIGINT = 0
, #rows BIGINT = 0
SET #LoopVar = 1
set #rows = 125000
insert into debug values(987654321)
insert into debug values(#LoopVar)
insert into debug values(#rows)
WHILE(#LoopVar <= #rows)
BEGIN
SET #LoopVar = #LoopVar + 1
WAITFOR DELAY '00:00:01'
insert into debug values(#LoopVar)
END
insert into debug values(123456789)
GO
The C++ code for running the stored procedure is:
RETCODE rc = SQL_SUCCESS;
HENV henv = SQL_NULL_HENV;
HDBC hdbc = SQL_NULL_HDBC;
SQLHSTMT hstmt = SQL_NULL_HSTMT;
SQLTCHAR * pszConnection = _T("DRIVER={SQL Server Native Client 10.0};Server=myserver;Trusted_Connection=Yes;Initial Catalog=testdb;");
SQLTCHAR * pszInsertStmt = _T("{call [testdb].[dbo].Add}");
SQLLEN cbParamLength;
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HENV, &henv);
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
SQLSetConnectAttr( hdbc, SQL_ATTR_LOGIN_TIMEOUT, reinterpret_cast<SQLPOINTER>(600), SQL_IS_UINTEGER);
SQLDriverConnect( hdbc, NULL, pszConnection, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
SQLSetStmtAttr(hstmt, SQL_QUERY_TIMEOUT, (SQLPOINTER)12000, SQL_IS_UINTEGER);
SQLSetStmtAttr(hstmt, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER)12000, SQL_IS_UINTEGER);
SQLINTEGER attr;
rc = SQLGetStmtAttr( hstmt, SQL_ATTR_QUERY_TIMEOUT, &attr, 0, NULL ) ;
rc = SQLGetStmtAttr( hstmt, SQL_QUERY_TIMEOUT, &attr, 0, NULL ) ;
rc = SQLGetConnectAttr(hdbc, SQL_ATTR_CONNECTION_TIMEOUT, &attr, 0, NULL);
rc = SQLExecDirect(hstmt, pszInsertStmt, SQL_NTS);
if (!SUCCESS(rc)) {
if (hstmt)
PrintError(SQL_HANDLE_STMT, hstmt);
if (hdbc)
PrintError(SQL_HANDLE_DBC, hdbc);
if(henv)
PrintError(SQL_HANDLE_ENV, henv);
}
if (hstmt)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
if (hdbc) {
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
if (henv)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
I have set query time in the code above. The connection time out is 0 (which I believe means no timeout). But no matter what I do, the stored procedure times out in 78 seconds. Does any one have any idea as to what I should do so that stored procedure can run indefinitely?
Please note if I run the stored procedure from SQL Server Management Studio directly, it works just fine..
Thanks in advance,
-Neel.
If anyone interested, the solution was to put "SET NOCOUNT ON" as the first line in stored procedure.
// SQLTables.cpp
// compile with: user32.lib odbc32.lib
#include <windows.h>
#include <sqlext.h>
#include <stdio.h>
// simple helper functions
int MySQLSuccess(SQLRETURN rc) {
return (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO);
}
struct DataBinding {
SQLSMALLINT TargetType;
SQLPOINTER TargetValuePtr;
SQLINTEGER BufferLength;
SQLLEN StrLen_or_Ind;
};
void printCatalog(const struct DataBinding* catalogResult, int numCols) {
for(int i = 0; i < numCols; i++)
if (catalogResult[i].StrLen_or_Ind != SQL_NULL_DATA)
printf("Catalog Name(%d) = %s \t", i + 1, (char *)catalogResult[i].TargetValuePtr);
printf("\n");
}
// remember to disconnect and free memory, and free statements and handles
int main() {
int bufferSize = 1024, i, numCols = 18;
struct DataBinding* catalogResult = (struct DataBinding*) malloc( numCols * sizeof(struct DataBinding) );
wchar_t* dbName = (wchar_t *)malloc( sizeof(wchar_t)*bufferSize );
wchar_t* userName = (wchar_t *)malloc( sizeof(wchar_t)*bufferSize );
// declare and initialize the environment, connection, statement handles
SQLHENV henv = NULL; // Environment
SQLHDBC hdbc = NULL; // Connection handle
SQLHSTMT hstmt = NULL; // Statement handle
SQLRETURN retCode;
HWND desktopHandle = GetDesktopWindow(); // desktop's window handle
SQLWCHAR connStrbuffer[1024];
SQLSMALLINT connStrBufferLen;
retCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
retCode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, -6);
retCode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
//retCode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)10, 0);
//retCode = SQLSetConnectAttr(hdbc,fOption,(SQLPOINTER)(size_t)param,0);
//retCode = SQLDriverConnect(hdbc, desktopHandle, (SQLCHAR*)"DSN=footballDB1;UID=\"\";PWD=\"\"", SQL_NTS, (SQLCHAR*)connStrbuffer, 1024 + 1, &connStrBufferLen, SQL_DRIVER_NOPROMPT);
retCode = SQLDriverConnect(hdbc, desktopHandle, (SQLCHAR*)"DSN=footballDB;UID=\"\";PWD=\"\"", SQL_NTS, (SQLCHAR*)connStrbuffer, 1024 + 1, &connStrBufferLen, SQL_DRIVER_NOPROMPT);
retCode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
retCode = SQLGetInfo(hdbc, SQL_DBMS_NAME , dbName, (SQLSMALLINT)bufferSize, (SQLSMALLINT *)&bufferSize);
printf("%s\n", dbName);
retCode = SQLGetInfo(hdbc, SQL_USER_NAME, userName, (SQLSMALLINT)bufferSize, (SQLSMALLINT *)&bufferSize);
bufferSize = 1024;
// allocate memory for the binding
// free this memory when done
for ( i = 0 ; i < numCols ; i++ ) {
catalogResult[i].TargetType = SQL_C_CHAR;
catalogResult[i].BufferLength = (bufferSize + 1);
catalogResult[i].TargetValuePtr = malloc( sizeof(unsigned char)*catalogResult[i].BufferLength );
}
// setup the binding (can be used even if the statement is closed by closeStatementHandle)
for ( i = 0 ; i < numCols ; i++ )
retCode = SQLBindCol(hstmt, (SQLUSMALLINT)i + 1, catalogResult[i].TargetType, catalogResult[i].TargetValuePtr, catalogResult[i].BufferLength, &(catalogResult[i].StrLen_or_Ind));
// all catalogs query
printf( "A list of names of all catalogs\n" );
//retCode = SQLTables( hstmt, (SQLCHAR*)"%", SQL_NTS, (SQLCHAR*)NULL, SQL_NTS, (SQLCHAR*)NULL, SQL_NTS, (SQLCHAR*)NULL, SQL_NTS );
retCode = SQLTables( hstmt, (unsigned char*)NULL, SQL_NTS, (unsigned char*)NULL, SQL_NTS, (unsigned char*)NULL, SQL_NTS, (unsigned char*)"'VIEW','TABLE'", SQL_NTS );
//retCode = SQLTables( hstmt, (SQLCHAR*)NULL, 0, (SQLCHAR*)"schema1", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"'VIEW','TABLE'", SQL_NTS );
//retCode = SQLTables( hstmt, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"%", SQL_NTS, (SQLCHAR*)"test", SQL_NTS);
//retCode = SQLColumns(hstmt, (SQLCHAR*)NULL, 0, (SQLCHAR*)NULL, SQL_NTS, (SQLCHAR*)"test", SQL_NTS, (SQLCHAR*)NULL, 0);
//retCode = SQLColumns(hstmt, (SQLCHAR*)NULL, 0, (SQLCHAR*)NULL, SQL_NTS, (SQLCHAR*)"CLAIMS_HISTORY_1", SQL_NTS, (SQLCHAR*)NULL, 0);
printf( "retCode = %d:%d\n", retCode, SQL_SUCCESS);
for ( retCode = SQLFetch(hstmt) ; MySQLSuccess(retCode) ; retCode = SQLFetch(hstmt) )
printCatalog( catalogResult, numCols );
getchar();
}
This piece of code is supposed to return the table names in a database and works for access databases saved with *.accdb (ie. the Microsoft Driver) extensions, which i am guessing is one of the latest drivers but i am not able to figure out why it does not work with the Driver do Microsoft Access ( *.mdb). can anyone tell me as to why this is happening?
this is a sample output when a DSN is created with the latest driver.
ACCESS
A list of names of all catalogs
retCode = 0:0
Catalog Name(1) = C:\Users\akisho02\Desktop\New folder (4)\football club db2.acc
db Catalog Name(3) = db_clubs Catalog Name(4) = TABLE Catalog
≡¡║ε½½½½½½½½■ε■ε■ε■ Catalog Name(18) =
Catalog Name(1) = C:\Users\akisho02\Desktop\New folder (4)\football club db2.acc
db Catalog Name(3) = db_items Catalog Name(4) = TABLE Catalog
≡¡║ε½½½½½½½½■ε■ε■ε■ Catalog Name(18) =
Catalog Name(1) = C:\Users\akisho02\Desktop\New folder (4)\football club db2.acc
db Catalog Name(3) = db_REGION Catalog Name(4) = TABLE Catalog
and this is a sample output when i create a DSN with the earlier drivers
ACCESS
A list of names of all catalogs
retCode = 0:0
Catalog Name(1) = C:\Users\akisho02\Desktop\football club db Catalog Name(3)
≡¡║ε½½½½½½½½■ε■ε■ε■ Catalog Name(18) = Catalog Name(6) =
Catalog Name(1) = C:\Users\akisho02\Desktop\football club db Catalog Name(3)
≡¡║ε½½½½½½½½■ε■ε■ε■ Catalog Name(18) = Catalog Name(6) =
Catalog Name(1) = C:\Users\akisho02\Desktop\football club db Catalog Name(3)
≡¡║ε½½½½½½½½■ε■ε■ε■ Catalog Name(18) = Catalog Name(6) =
This is a bug I saw with microsoft access driviers. I would suggest you use the latest version that the system offers in while setting up your database connection.