I am working on a project that requires me to perform insert query on an MS Access table. I have been searching everywhere online but nothing seems to work. Any help would be greatly appreciated. Also, I have to write this for VS2008 and and Visual C++ 6.0. Thanks
You have (far too) many choices: ADO/RDO, DAO, ODBC, and OLE DB, to name only a few. DAO is officially deprecated. ADO/RDO aren't officially, but MS doesn't seem to care much about them anymore either. With VC 6, however, obsolescent is pretty much a fact of life. I believe they're all still supported to at least some degree under VS 2008, but they no longer, for example, include any wizards to help with using DAO.
That basically leaves OLE DB and ODBC as your first couple of choices. MS is still actively supporting and developing them, and the others are unlikely to provide any major advantage anyway.
I should add that VC++ 6.0 provides quite a few features missing from VS2008 for writing applications that use databases. You might want to look at what I showed in a previous question for some guidance.
Use ODBC. Example of connecting to database and executing INSERT query:
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <sqlext.h>
WCHAR szDSN[] = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='';DBQ=C:\\users.mdb";
int _tmain(int argc, _TCHAR* argv[])
{
HENV hEnv;
HDBC hDbc;
/* ODBC API return status */
RETCODE rc;
int iConnStrLength2Ptr;
WCHAR szConnStrOut[256];
WCHAR* query = L"INSERT INTO [Users] (name,surname) VALUES ('John','Smith');";
HSTMT hStmt;
/* Allocate an environment handle */
rc = SQLAllocEnv(&hEnv);
/* Allocate a connection handle */
rc = SQLAllocConnect(hEnv, &hDbc);
/* Connect to the database */
rc = SQLDriverConnect(hDbc, NULL, (WCHAR*)szDSN,
SQL_NTS, (WCHAR*)szConnStrOut,
255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(rc))
{
wprintf(L"Successfully connected to database. Data source name: \n %s\n",
szConnStrOut);
/* Prepare SQL query */
wprintf(L"SQL query:\n %s\n", query);
rc = SQLAllocStmt(hDbc,&hStmt);
rc = SQLPrepare(hStmt, query, SQL_NTS);
/* Excecute the query */
rc = SQLExecute(hStmt);
if (SQL_SUCCEEDED(rc))
{
wprintf(L"SQL Success\n");
}
else{
wprintf(L"SQL Failed\n");
}
}
else
{
wprintf(L"Couldn't connect to %s.\n",szDSN);
}
/* Disconnect and free up allocated handles */
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
getchar();
return 0;
}
Source: https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2007/cc811599(v=office.12)
Related
I made a PostgreSQL30 data source name. I tested it and I managed to connect to that dsn through ODBC data source window manager. There was a button Test and It showed message dialog, telling me that connection was success.
Now I wonder how would I connect to that DSN through c++ code and get some data.
This is my code, i saw few examplex online and come up with this code
enter code here
HENV hEnv = NULL; // for allocating memory usingSQLAllocEnv
HDBC hDBC = NULL; // connection handler
HSTMT hStmt = NULL; // statement handler
const char* szDSN = "PostgreSQL30"; // DataSourceName (config in windows
control panel)
const char* szUID = "postgres"; //username of the database
const char* szPasswd = "postgres"; //password of the database
RETCODE retcode;
int rcod = 1;
int i, j, no = 2;
int main()
{
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
std::cout << retcode << std::endl;
SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
retcode = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDBC);
std::cout << retcode << std::endl;
retcode = SQLConnectA(hDBC,(SQLCHAR*)szDSN, SQL_NTS, (SQLCHAR*)szUID, SQL_NTS,
(SQLCHAR*)szPasswd,
SQL_NTS);
std::cout << (SQLCHAR*)szUID << std::endl;
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
// connected!!
std::cout << "Hello World!\n SUCCESSS COME ON PLEASE";
}
else {
std::cout << retcode << std::endl;
}
SQLFreeHandle(SQL_HANDLE_ENV, &hEnv);
SQLFreeHandle(SQL_HANDLE_DBC, &hDBC);
}
But I cant comprehend why would this work, I mean how is this code knows to call SQLAllocHandle implemented by Postgres driver ?
My question is how would I connect to DSN thorugh C++ code and get some data
In fact ODBC Driver Manager makes these calls to ODBC driver when performing your SQLConnect call: on this stage it "knows" which driver you want to use. Look at the SQLConnect function description, "Comments" section:
"The Driver Manager does not connect to a driver until the application calls a function (SQLConnect, SQLDriverConnect, or SQLBrowseConnect) to connect to the driver. Until that point, the Driver Manager works with its own handles and manages connection information. When the application calls a connection function, the Driver Manager checks whether a driver is currently connected to for the specified ConnectionHandle:
If a driver is not connected to, the Driver Manager connects to the driver and calls SQLAllocHandle with a HandleType of SQL_HANDLE_ENV, SQLAllocHandle with a HandleType of SQL_HANDLE_DBC, SQLSetConnectAttr (if the application specified any connection attributes), and the connection function in the driver. The Driver Manager returns SQLSTATE IM006 (Driver's SQLSetConnectOption failed) and SQL_SUCCESS_WITH_INFO for the connection function if the driver returned an error for SQLSetConnectAttr. For more information, see Connecting to a Data Source or Driver.
If the specified driver is already connected to on the ConnectionHandle, the Driver Manager calls only the connection function in the driver. In this case, the driver must make sure that all connection attributes for the ConnectionHandle maintain their current settings.
If a different driver is connected to, the Driver Manager calls SQLFreeHandle with a HandleType of SQL_HANDLE_DBC, and then, if no other driver is connected to in that environment, it calls SQLFreeHandle with a HandleType of SQL_HANDLE_ENV in the connected driver and then disconnects that driver. It then performs the same operations as when a driver is not connected to.
The driver then allocates handles and initializes itself."
Full text here: SQLConnect function comments
const char* szDSN = "PostgreSQL30"; // DataSourceName (config in windows
control panel)
If you check in the ODBC Data source, This DSN (PostgreSQL30) would be created using an appropriate driver. The driver manager knows which driver to load based on the configured ODBC data source information.
I'm using Microsoft's ODBC driver to connect a C++/Linux application to a SQL Server database running remotely, and when I try to connect to the database, the call fails with SQL_INVALID_HANDLE. Reading through their documentation, I find this:
SQL_INVALID_HANDLE Function failed due to an invalid environment, connection, statement, or descriptor handle. This indicates a programming error. No additional information is available from SQLGetDiagRec or SQLGetDiagField. This code is returned only when the handle is a null pointer or is the wrong type, such as when a statement handle is passed for an argument that requires a connection handle.
Fair enough, but at no point in the creation of the handles and environment prior to the connect statement do I get any errors. Also, for the second argument, their documentation says I can pass in a null pointer if there is no desktop window (as is the case on this linux console application). Here is a MVCE, adapted from Microsoft's example program:
#include "sql.h"
#include "sqlext.h"
#include "msodbcsql.h"
#include <iostream>
#include <string>
int main(int, char**)
{
using std::cerr;
using std::endl;
SQLHENV henv;
SQLHDBC hdbc;
HWND dhandle = nullptr; // no desktop handle in linux
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLCHAR OutConnStr[255];
SQLSMALLINT OutConnStrLen;
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (!(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO))
cerr << "SQLAllocHandle (environment) failed " << retcode << endl;
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
if (!(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO))
cerr << "SQLSetEnvAttr failed " << retcode << endl;
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
if (!(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO))
cerr << "SQLAllocHandle (connection) failed " << retcode << endl;
retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
if (!(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO))
cerr << "SQLSetConnectAttr failed " << retcode << endl;
std::string dsn = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=*.*.*,1433;DATABASE=***;UID=***;PWD=***";
retcode = SQLDriverConnect(hdbc, dhandle, (SQLCHAR*)dsn.c_str(), dsn.length(), OutConnStr, 255, &OutConnStrLen, SQL_DRIVER_PROMPT);
if (!(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO))
cerr << "SQLDriverConnect failed " << retcode << endl;
// cleanup code redacted for brevity
return 0;
}
The program outputs SQLDriverConnect failed -2, which is SQL_INVALID_HANDLE. I'm stumped. hdbc is clearly the right type, and examining it in the debugger shows me it is not null.
It may be worth noting that the exact same connection string works in a python program using pyodbc. It seems that the C++ program isn't even getting as far as looking at that string, though. It just doesn't like the handle I'm sending into the connect call.
Microsoft's documentation clearly says they provide no additional information. If anyone can provide any direction on how to diagnose/debug this, I'd appreciate it greatly.
This application uses gcc 4.9.1 on Centos 7.
After two weeks of digging, this turned out to be some kind of versioning problem.
Eventually, this program will be doing some BCP uploads via Microsoft's extensions in libmsodbcsql.so. It turns out that library also has implementations of many of the SQL* functions, which are the ones that are failing in this test program. When I change the order of the link so that libodbc.so is before the MSFT extensions library so that the loader finds those implementations first, the program works fine.
I'm curious why this is, and it probably points to something else I'm doing wrong that may bite me down the road. But for now, at least, I am able to get connected to the database and do basic queries and updates.
Thanks to those who helped.
In Unix does the handle not have to be a non-null value for dialogs to be displayed.
For any handle in SQL Server, it has to be allocated before used!
So the order is Environment, Connection and Statement.
Example:
SQLHENV hEnv = nullptr;
SQLHDBC hDbc = nullptr;
SQLHSTMT hStmt = NULL;
Allocations
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);
Below is sample code that may help you.
Basics fast,
Create table in your sql server database and insert some data
create table test (id int, name nvarchar(128));
Insert some data
insert into test (id,name) values (1, 'Awesome Name');
C++ Code to query items in the table
#include <iostream>
#include <string>
#include <sql.h>
#include <sqlext.h>
int main(int argc, char **argv) {
SQLHENV hEnv = nullptr;
SQLHDBC hDbc = nullptr;
SQLHSTMT hStmt = NULL;
/**
* Allocate environment handle
*/
SQLRETURN allocReturn = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
//Set environment
SQLRETURN setEnvReturn = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
//Allocate connection handle
SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
SQLCHAR *connection_string = (SQLCHAR *)
"DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost,1433;DATABASE=database;UID=sa;PWD=password";
//Connect to database
SQLRETURN connReturn = SQLDriverConnect(hDbc, NULL, connection_string, SQL_NTS, NULL, 0, NULL,
SQL_DRIVER_COMPLETE);
//Allocate Statement Handle
SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);
//Create statement
SQLCHAR *query = (SQLCHAR *) "SELECT * FROM TEST;";
SQLRETURN sqlPrepareResponse = SQLPrepare(hStmt, query, SQL_NTS); //strlen(reinterpret_cast<const char *>(query))
//Bind columns
SQLCHAR personName[20];
SQLLEN personNameIndex;
SQLRETURN bindNameResponse = SQLBindCol(hStmt, 2, SQL_C_CHAR, personName, sizeof(personName),
&personNameIndex);
SQLINTEGER personId;
SQLLEN personIdIndex;
SQLRETURN personIdBindResponse = SQLBindCol(hStmt, 1, SQL_INTEGER, &personId, 0, &personIdIndex);
SQLRETURN execResponse = SQLExecute(hStmt);
SQLRETURN fetchResponse;
while ((fetchResponse = SQLFetch(hStmt)) != SQL_NO_DATA) {
std::cout << "ID: [" << personId << "] :" << personName << std::endl;
}
/* Free the statement handle. */
SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
/* Disconnect from the database. */
SQLDisconnect(hDbc);
/* Free the connection handle. */
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
/* Free the environment handle. */
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
return EXIT_SUCCESS;
}
I have exactly the same error using similar code (that was working in Ubuntu 18.04, but not with a update to 20.04)
cat /etc/odbcinst.ini
[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.5.so.2.1
UsageCount=1
using this connection string
DRIVER=ODBC Driver 17 for SQL Server;SERVER=127.0.0.1, 1433;UID=SA;PWD=password;DATABASE=my_database;
this is my library link order
if(UNIX)
find_program(LSB_RELEASE_EXEC lsb_release)
execute_process(COMMAND ${LSB_RELEASE_EXEC} -is OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Building in " ${LSB_RELEASE_ID_SHORT})
if("${LSB_RELEASE_ID_SHORT}" STREQUAL "Ubuntu")
message(STATUS "Linking with SQL-Server library")
set(lib_dep ${lib_dep} msodbcsql-17)
endif()
set(lib_dep ${lib_dep} pthread odbc dl)
endif()
As noted in the solution above, changing the link order fixed the problem
set(lib_dep ${lib_dep} pthread odbc dl msodbcsql-17)
Database: Microsoft SQL Server - any version
Preferably the easiest way (without connecting third-party libraries). You just need to test connectivity
In the task cannot be used .Net Framework and it is not advisable to MFC
The project in Visual Studio 2008 Professional
CDatabase * db = new CDatabase ();
if (!db->OpenEx (args [2], CDatabase::noOdbcDialog))
{
printf ("Failed to connect to DB\n");
ExitProcess (1);
}
db->Close();
This code on the MFC is not suitable because it requires the installation of Redistributable.
It is desirable to use the WinAPI.
Thank you for your attention.
UPD:
SQLHANDLE hEnv, hDbc;
SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
SQLSetEnvAttr (hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, NULL);
SQLAllocHandle (SQL_HANDLE_DBC, hEnv, &hDbc);
LPSTR lpConnectionString = args [2];
LPSTR lpOutputString = new CHAR [256];
SQLSMALLINT sLength;
SQLRETURN sqlRet = SQLDriverConnect(hDbc, 0, (SQLCHAR*)lpConnectionString, strlen (lpConnectionString), (SQLCHAR*)lpOutputString, 255, &sLength, SQL_DRIVER_NOPROMPT);
args[2] = "DRIVER={SQL Server};SERVER={VM7\SQLEXPRESS};Database={master}";
VM7 is name of my machine
There are only 2 'Native' database libraries that ship with Windows. They are ODBC and OLEDB. Given that OLEDB is a COM based interface and requires significantly more knowledge I'm only going to discuss the ODBC solution here.
The code below is bare bones and is there only to provide hints on how to solve the problem.
#include <Windows.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#define MAX_STRING_LEN 255
int main()
{
SQLHANDLE henv, hdbc;
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_ODBC_VER, SQL_IS_INTEGER);
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
wchar_t* connection_string = L"Driver={SQL Server};Server=<address>;Database=<database name>;Uid=<username>;Pwd=<password>";
wchar_t output_string[MAX_STRING_LEN + 1];
SQLSMALLINT out_length;
SQLDriverConnect(hdbc, 0, connection_string, lstrlen(connection_string), output_string, MAX_STRING_LEN, &out_length, SQL_DRIVER_NOPROMPT);
}
We create and cache ODBC connections created using SQLDriverConnect; we've found circumstances where the connection becomes lost... prepared statements stop working, etc.
I didn't see an obvious function to test a connection/statement is valid, or to reset/re-create a connection, which seems like it would be a fairly common pattern. Can anyone suggest how this is best implemented?
This answer is along the same lines, is that the correct solution here too? If so is there any neat way to 're-boot' an existing statement to use the new connection? And if a connection is discovered to be dead does it still need to be freed?
In my mind there has always been some confusion over whether SQL_ATTR_CONNECTION_DEAD works to test if a connection is still alive before you make a call which requires it to be alive. This is based on the usage of many ODBC drivers, including the ones I wrote and I suspect they may all implement it differently.
In the post you refer to Nick's answer (SQL_ATTR_CONNECTION_DEAD) does not work with many drivers I have access to:
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
#include <stdlib.h>
static void extract_error(
char *fn,
SQLHANDLE handle,
SQLSMALLINT type);
main() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLCHAR outstr[1024];
SQLSMALLINT outstr_len;
SQLRETURN ret;
SQLINTEGER dead;
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
ret = SQLDriverConnect(hdbc, (void *)0, "DSN=xx;UID=xx;PWD=xx", SQL_NTS,
outstr, sizeof(outstr), &outstr_len,
SQL_DRIVER_COMPLETE);
if (!SQL_SUCCEEDED(ret)) {
extract_error("SQLDriverConnect", hdbc, SQL_HANDLE_DBC);
exit(1);
}
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
ret = SQLPrepare(hstmt, "select 123", SQL_NTS);
if (!SQL_SUCCEEDED(ret)) {
extract_error("SQLPrepare", hstmt, SQL_HANDLE_STMT);
exit(1);
}
ret = SQLExecute(hstmt);
if (!SQL_SUCCEEDED(ret)) {
extract_error("SQLExecute", hstmt, SQL_HANDLE_STMT);
exit(1);
}
sleep(120);
SQLGetConnectAttr(hdbc, SQL_ATTR_CONNECTION_DEAD, &dead, 0, NULL);
printf ("dead=%ld\n", dead);
ret = SQLExecute(hstmt);
if (!SQL_SUCCEEDED(ret)) {
extract_error("SQLExecute", hstmt, SQL_HANDLE_STMT);
}
SQLGetConnectAttr(hdbc, SQL_ATTR_CONNECTION_DEAD, &dead, 0, NULL);
printf ("dead=%ld\n", dead);
}
static void extract_error(
char *fn,
SQLHANDLE handle,
SQLSMALLINT type)
{
SQLINTEGER i = 0, native;
SQLCHAR state[ 7 ];
SQLCHAR text[256];
SQLSMALLINT len;
int ret;
fprintf(stderr,
"\n"
"The driver reported the following diagnostics whilst running "
"%s\n\n",
fn);
do
{
ret = SQLGetDiagRec(type, handle, ++i, state, &native, text,
sizeof(text), &len );
if (SQL_SUCCEEDED(ret))
printf( "%s:%ld:%ld:%s\n", state, i, native, text );
}
while( ret == SQL_SUCCESS );
}
which outputs with a number of drivers:
dead=0
# At this point I took the server down
The driver reported the following diagnostics whilst running SQLExecute
08S01:1:0:[SQL Server Driver 10.0][SQL Server]Communication link failure: short write
dead=0
The other option specified in the post you refer to is SQL_COPT_SS_CONNECTION_DEAD but that is specific to MS SQL Server.
Since I presume you don't intend for any statement handles to fail ordinarily can't you just run the stmt and if it fails assume the connection is dead and reconnect and reprepare?
If a connection does die you do still need to call SQLFreeHandle for the various handles.
My subject is somewhat stupid and complex for me. I'm trying to make a very simple connection with an Access 2007 db, but the connection never happens. I'm trying to see what happens with SQLGetDiagRec(), but the program crashes when SQLGetDiagRec() is executed. I'm not that much into C++, so I'm stuck for the past few days in this. Any help will be highly appreciated. I'm using Visual C++ 2008.
EDIT: After changing the character set from Unicode to Multibyte, I was able to execute the SQLGetDiagRec. I, then, changed my two pointers from int and char to SQLSMALLINT and SQLCHAR and, bam, it worked. Thanx a lot for the heads up guys.
#include "stdafx.h"
#include <windows.h>
#include <conio.h>
#include <iostream>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
char szDSN[256] = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DSN='Hospital_mdb';DBQ=C:\\Hospital.mdb;";
SQLHANDLE EnvHandlePtr;
SQLHANDLE ConHandle;
SQLHANDLE StmtHandle;
SQLRETURN rc;
SQLSMALLINT iConnStrLength2Ptr; // Changing from int iConnStrLength2Ptr;
SQLCHAR szConnStrOut[256]; //changing from char szConnStrOut[256];
SQLCHAR SQLState[6], Msg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER NativeError;
SQLSMALLINT MsgLen;
if ( (rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &EnvHandlePtr)) == SQL_SUCCESS){
printf("Environment Set!");
if( (rc = SQLSetEnvAttr(EnvHandlePtr, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3, SQL_IS_UINTEGER))==SQL_SUCCESS ){
printf("Driver Set!");
if ( (rc = SQLAllocHandle(SQL_HANDLE_DBC, EnvHandlePtr, &ConHandle))==SQL_SUCCESS ){
printf("Allocation Done!");//**so far, so good, but then the connection doesn't happen**
rc = SQLDriverConnect(ConHandle, NULL, (SQLWCHAR*)szDSN,
SQL_NTS, (SQLWCHAR*) szConnStrOut, 0, (SQLSMALLINT*) iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
if ( rc == SQL_SUCCESS ){
//if ( (rc = SQLConnect(ConHandle, (SQLWCHAR*)szDSN, SQL_NTS, (SQLWCHAR*)"", SQL_NTS, (SQLWCHAR*)"", SQL_NTS))== SQL_SUCCESS ){
printf("Connection Done");
}//end of Connection clause
else{
SQLGetDiagRec(SQL_HANDLE_DBC, ConHandle, 1, (SQLWCHAR*)SQLState, &NativeError, (SQLWCHAR*)Msg, sizeof(Msg), &MsgLen);
printf("Connection Failed\n%s", Msg);
}
SQLDisconnect(ConHandle);
}//end of Connection Allocation clause
SQLFreeHandle(SQL_HANDLE_DBC, ConHandle);
}//end of Driver clause
SQLFreeHandle(SQL_HANDLE_ENV, EnvHandlePtr);
}//end of Enviroment clause
_getch();
}//end of main
You are casting the diagnostics that the compiler generates for your bad code away. At least SQLState is bad, you are passing a 6 byte buffer when 12 bytes are written. That corrupts the stack frame. The SQLDriverConnect call cannot work for the same reason.
Remove all casts by declaring your local variables properly.
And use Unicode in your code. You could disable it in your project settings but that's never not a mistake when you work with a dbase.