C++ Acess console application - c++

connection to access is normal, the SQL query is executed, I get a SQL Success response. and I can't do it anymore. how to get data from sql query
int bdacess(int argc, char* argv[])
{
/* 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;
}
I can't get the result of sql execution itself

Related

Is there a way to query .accdb/.mdb files with C++?

I have a school project where I need to develop an application that queries and writes into Access database files, but using C++.
After some research I found about ODBC, and that it could help me, but I had no luck. I've tried differents connection strings, but nothing seems to work.
What I've done so far:
#include "pch.h"
#include <windows.h>
#include <sqlext.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
char szDSN[256] = "Driver={Microsoft Access Driver (*.mdb,
*.accdb)};DBQ=C:\\EntrySystem.mdb";
/* Data Access Method used in this sample */
const char* DAM = "Direct ODBC";
HENV hEnv;
HDBC hDbc;
/* ODBC API return status */
RETCODE rc;
int iConnStrLength2Ptr;
char szConnStrOut[256];
unsigned char query[] = "SELECT * from Condomino;";
SQLCHAR chval1[128], chval2[128], colName[128];
int ret1;
int ret2;
/* Number of rows and columns in result set */
SQLINTEGER rowCount = 0;
SQLSMALLINT fieldCount = 0, currentField = 0;
HSTMT hStmt;
/* Allocate an environment handle */
rc = SQLAllocEnv(&hEnv);
/* Allocate a connection handle */
rc = SQLAllocConnect(hEnv, &hDbc);
/* Connect to the 'Northwind 2007.accdb' database */
rc = SQLDriverConnect(hDbc, NULL, (SQLWCHAR*)szDSN,
SQL_NTS, (SQLWCHAR*)szConnStrOut,
255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(rc))
{
printf("%s: Successfully connected to database. Data source name: \n %s\n",
DAM, szConnStrOut);
/* Prepare SQL query */
printf("%s: SQL query:\n %s\n", DAM, query);
rc = SQLAllocStmt(hDbc, &hStmt);
rc = SQLPrepare(hStmt, (SQLWCHAR*)query, SQL_NTS);
/* Bind result set columns to the local buffers */
rc = SQLBindCol(hStmt, 1, SQL_C_CHAR, chval1, 128, (SQLINTEGER*)&ret1);
rc = SQLBindCol(hStmt, 2, SQL_C_CHAR, chval2, 128, (SQLINTEGER*)&ret2);
/* Excecute the query and create a record set */
rc = SQLExecute(hStmt);
if (SQL_SUCCEEDED(rc))
{
printf("%s: Retrieve schema info for the given result set:\n", DAM);
SQLNumResultCols(hStmt, &fieldCount);
if (fieldCount > 0)
{
for (currentField = 1; currentField <= fieldCount; currentField++)
{
SQLDescribeCol(hStmt, currentField,
(SQLWCHAR*)colName, sizeof(colName), 0, 0, 0, 0, 0);
printf(" | %s", colName);
}
printf("\n");
}
else
{
printf("%s: Error: Number of fields in the result set is 0.\n", DAM);
}
printf("%s: Fetch the actual data:\n", DAM);
/* Loop through the rows in the result set */
rc = SQLFetch(hStmt);
while (SQL_SUCCEEDED(rc))
{
printf(" | %s | %s\n", chval1, chval2);
rc = SQLFetch(hStmt);
rowCount++;
};
printf("%s: Total Row Count: %d\n", DAM, rowCount);
rc = SQLFreeStmt(hStmt, SQL_DROP);
}
}
else
{
printf("%s: Couldn't connect to %s.\nLastError: %d\n", DAM, szDSN, GetLastError());
}
/* Disconnect and free up allocated handles */
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
printf("%s: Cleanup. Done.\n", DAM);
return 0;
}
I expect it to query all rows from my table "condomino", but the library (sqlext) keep giving me the error "0". Any help would be welcome, if you any other solutions, let me know.
Yes.
Seems like you are having issue with Access connection strings. An alternative is to create User DNS ; go to control panel / administrative tools / ODBC Data Source / choose Microsoft Access Database - configure and set your path to your *.mdb ( use of *.accdb recommended)
Now your connection string will be simplified as ( driver name is case sensitive ):
SQLWCHAR outstr[1024];
SQLSMALLINT outstrlen;
SQLReturnCode = SQLDriverConnect(hDatabase, NULL, L"DSN=Microsoft Access Driver;", SQL_NTS,
outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);

C++ ODBC SQL - Insert into table not working

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

How do I setup an ODBC connection to perform multiple querys(SQLExecDirect) in c++?

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

Read Custom String From File in Connection

How to make this to read from custom string the information
I would like to read Host,User,Password,Database from the custom string, how can i do that?
Also another problem here in code is that it show that is connected with ODBC , but it doesnt read anything from database
GetPrivateProfileStringA("SQL","Host","127.0.0.1",szServer2,sizeof(szServer2),SQL_PATH);
GetPrivateProfileStringA("SQL","User","sa",szUser,sizeof(szUser),SQL_PATH);
GetPrivateProfileStringA("SQL","Password","12345",szPassword,sizeof(szPassword),SQL_PATH);
GetPrivateProfileStringA("SQL","Database","DbName",szDatabase,sizeof(szDatabase),SQL_PATH);
BOOL SQLCONNECT::Connect()
{
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLRETURN ret;
SQLSMALLINT columns;
int row = 0;
/* Allocate an environment handle */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* We want ODBC 3 support */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
/* Allocate a connection handle */
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
/* Connect to the DSN */
SQLDriverConnectW(dbc, NULL, L"DRIVER={SQL Server};SERVER=(local);DATABASE=DbName;UID=sa;PWD=password;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
/* Check for success */
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt))
{
MessageBoxA(0, "Failed to connect to Database!", "Error", MB_OK);
}
std::cin.get();
return FALSE;
}

Access database connectivity in C++

I am trying to connect MS access database in C++ using C-Free 5.0 compiler. I found the following code from internet but it is giving me an error as:
[Error] C:\Users\rubeea\Documents\C-Free\Temp\db.cpp:25: error: invalid conversion from const char*' tounsigned char*'
Here's the code:
#include<windows.h>
#include<sqlext.h>
#include<stdio.h>
#include <sql.h>
int main(void){
char szDSN[256] = "Driver=std;DSN='';DBQ=E:\\student.mdb;";
/* Data Access Method used in this sample */
const char* DAM = "Direct ODBC";
HENV hEnv;
HDBC hDbc;
/* ODBC API return status */
RETCODE rc;
int iConnStrLength2Ptr;
char szConnStrOut[256];
unsigned char* query ="SELECT faculty.[name], faculty.[remarks] FROM faculty;";
SQLCHAR chval1[128], chval2[128], colName[128];
int ret1;
int ret2;
/* Number of rows and columns in result set */
SQLINTEGER rowCount = 0;
SQLSMALLINT fieldCount = 0, currentField = 0;
HSTMT hStmt;
/* Allocate an environment handle */
rc = SQLAllocEnv(&hEnv);
/* Allocate a connection handle */
rc = SQLAllocConnect(hEnv, &hDbc);
/* Connect to the 'student.accdb' database */
rc = SQLDriverConnect(hDbc, NULL, (unsigned char*)szDSN,
SQL_NTS, (unsigned char*)szConnStrOut,
255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(rc))
{
printf("%s: Successfully connected to database. Data source name: \n %s\n",
DAM, szConnStrOut);
/* Prepare SQL query */
printf("%s: SQL query:\n %s\n", DAM, query);
rc = SQLAllocStmt(hDbc,&hStmt); rc = SQLPrepare(hStmt, query, SQL_NTS);
/* Bind result set columns to the local buffers */
rc = SQLBindCol(hStmt, 1, SQL_C_CHAR, chval1, 128, (SQLINTEGER*)&ret1);
rc = SQLBindCol(hStmt, 2, SQL_C_CHAR, chval2, 128, (SQLINTEGER*)&ret2);
/* Execute the query and create a record set */
rc = SQLExecute(hStmt);
if (SQL_SUCCEEDED(rc))
{
printf("%s: Retrieve schema info for the given result set:\n", DAM);
SQLNumResultCols(hStmt, &fieldCount);
if (fieldCount > 0)
{
for (currentField=1; currentField <= fieldCount; currentField++)
{
SQLDescribeCol(hStmt, currentField,
colName, sizeof(colName), 0, 0, 0, 0, 0);
printf(" | %s", colName);
}
printf("\n");
}
else
{
printf("%s: Error: Number of fields in the result set is 0.\n", DAM);
}
printf("%s: Fetch the actual data:\n", DAM);
/* Loop through the rows in the result set */
rc = SQLFetch(hStmt);
while (SQL_SUCCEEDED(rc))
{
printf(" | %s | %s\n", chval1, chval2);
rc = SQLFetch(hStmt);
rowCount++;
};
printf("%s: Total Row Count: %d\n", DAM, rowCount);
rc = SQLFreeStmt(hStmt, SQL_DROP);
}
}
else
{`enter code here`
printf("%s: Couldn't connect to %s.\n", DAM, szDSN);
}
/* Disconnect and free up allocated handles */
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
printf("%s: Cleanup. Done.\n", DAM);
return 0;
}