Dancindan84
asked on
C++ ODBC Again
Ok, now that the below is working, I'd like something one step better. :-) It would make my life a whole lot easier if the function was "void ODBCConnection(string statement)" and then statement was somehow converted into UCHAR szSqlStr[]; Is there a way to do that? Thanks again.
#include <windows.h>
#include <sqlext.h>
#include <stdio.h>
#include <iostream>
void ODBCConnection(UCHAR szSqlStr[])
{
cout << szSqlStr;
HENV hEnv = NULL; // Env Handle from SQLAllocEnv()
HDBC hDBC = NULL; // Connection handle
HSTMT hStmt = NULL; // Statement handle
UCHAR szDSN[SQL_MAX_DSN_LENGTH] = "Employee"; // Data Source Name buffer
UCHAR* szUID = NULL; // User ID buffer
UCHAR* szPasswd = NULL; // Password buffer
UCHAR szModel[128]; // Model buffer
SDWORD cbModel; // Model buffer bytes recieved
//UCHAR szSqlStr [] = "SELECT * FROM Employee"; // SQL string
RETCODE retcode; // Return code
// Allocate memory for ODBC Environment handle
SQLAllocEnv (&hEnv);
// Allocate memory for the connection handle
SQLAllocConnect (hEnv, &hDBC);
// Connect to the data source "db97" using userid and password.
retcode = SQLConnect (hDBC, szDSN, SQL_NTS, szUID, SQL_NTS, szPasswd, SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
// Allocate memory for the statement handle
retcode = SQLAllocStmt (hDBC, &hStmt);
// Prepare the SQL statement by assigning it to the statement handle
retcode = SQLPrepare (hStmt, szSqlStr, strlen ( (const char * ) szSqlStr ));
// Execute the SQL statement handle
retcode = SQLExecute (hStmt);
// Project only column 2 which is the regions
SQLBindCol (hStmt, 2, SQL_C_CHAR, szModel, sizeof(szModel), &cbModel);
// Get row of data from the result set defined above in the statement
retcode = SQLFetch (hStmt);
while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
printf ("\t%s\n", szModel); // Print row (model)
retcode = SQLFetch (hStmt); // Fetch next row from result set
}
// Free the allocated statement handle
SQLFreeStmt (hStmt, SQL_DROP);
// Disconnect from datasource
SQLDisconnect (hDBC);
}
// Free the allocated connection handle
SQLFreeConnect (hDBC);
// Free the allocated ODBC environment handle
SQLFreeEnv (hEnv);
return;
}
#include <windows.h>
#include <sqlext.h>
#include <stdio.h>
#include <iostream>
void ODBCConnection(UCHAR szSqlStr[])
{
cout << szSqlStr;
HENV hEnv = NULL; // Env Handle from SQLAllocEnv()
HDBC hDBC = NULL; // Connection handle
HSTMT hStmt = NULL; // Statement handle
UCHAR szDSN[SQL_MAX_DSN_LENGTH] = "Employee"; // Data Source Name buffer
UCHAR* szUID = NULL; // User ID buffer
UCHAR* szPasswd = NULL; // Password buffer
UCHAR szModel[128]; // Model buffer
SDWORD cbModel; // Model buffer bytes recieved
//UCHAR szSqlStr [] = "SELECT * FROM Employee"; // SQL string
RETCODE retcode; // Return code
// Allocate memory for ODBC Environment handle
SQLAllocEnv (&hEnv);
// Allocate memory for the connection handle
SQLAllocConnect (hEnv, &hDBC);
// Connect to the data source "db97" using userid and password.
retcode = SQLConnect (hDBC, szDSN, SQL_NTS, szUID, SQL_NTS, szPasswd, SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
// Allocate memory for the statement handle
retcode = SQLAllocStmt (hDBC, &hStmt);
// Prepare the SQL statement by assigning it to the statement handle
retcode = SQLPrepare (hStmt, szSqlStr, strlen ( (const char * ) szSqlStr ));
// Execute the SQL statement handle
retcode = SQLExecute (hStmt);
// Project only column 2 which is the regions
SQLBindCol (hStmt, 2, SQL_C_CHAR, szModel, sizeof(szModel), &cbModel);
// Get row of data from the result set defined above in the statement
retcode = SQLFetch (hStmt);
while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
printf ("\t%s\n", szModel); // Print row (model)
retcode = SQLFetch (hStmt); // Fetch next row from result set
}
// Free the allocated statement handle
SQLFreeStmt (hStmt, SQL_DROP);
// Disconnect from datasource
SQLDisconnect (hDBC);
}
// Free the allocated connection handle
SQLFreeConnect (hDBC);
// Free the allocated ODBC environment handle
SQLFreeEnv (hEnv);
return;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Basically when u say
UCHAR *ptr = ( UCHAR *) str.c_str()
It stores the "starting address of the memory where the string in str is stored" in ptr
Thus, ptr also points to the same memory location as that of the string in str
Now, somehow, if str gets modifed, then ptr would again point to the same location (thus having new value OR may be some garbage because the STL string may allocate a new memory to store the new value if the value may be bigger)
The following code shows an example
int main(int argc, char* argv[])
{
UCHAR *ptr ;
string s = "Trial" ;
ptr = (UCHAR * ) s.c_str () ;
cout << endl << ptr ;
s = "Hello" ;
cout << endl << ptr ;
system("pause");
return 0;
}
Amit
UCHAR *ptr = ( UCHAR *) str.c_str()
It stores the "starting address of the memory where the string in str is stored" in ptr
Thus, ptr also points to the same memory location as that of the string in str
Now, somehow, if str gets modifed, then ptr would again point to the same location (thus having new value OR may be some garbage because the STL string may allocate a new memory to store the new value if the value may be bigger)
The following code shows an example
int main(int argc, char* argv[])
{
UCHAR *ptr ;
string s = "Trial" ;
ptr = (UCHAR * ) s.c_str () ;
cout << endl << ptr ;
s = "Hello" ;
cout << endl << ptr ;
system("pause");
return 0;
}
Amit
The best function prototype in your case is:
void ODBCConnection(const char* szSqlStr)
{
cout << szSqlStr;
...
retcode = SQLPrepare (hStmt, szSqlStr, strlen (szSqlStr ));
...
}
Caller may pass to this function [const] char*, unsigned char*, char[], unsigned char[], std::string or CString. If compiler doesn't like caller code, make casting there. std::string should be passed by the way described by Sys_Prog (c_str). CString has i's own const char* operator.
Declaration of ODBCConnection function by such way shows that function gets constant pointer to string, it doesn't change it. You may use also Windows alias for const char*:
void ODBCConnection(LPCSTR szSqlStr)
void ODBCConnection(const char* szSqlStr)
{
cout << szSqlStr;
...
retcode = SQLPrepare (hStmt, szSqlStr, strlen (szSqlStr ));
...
}
Caller may pass to this function [const] char*, unsigned char*, char[], unsigned char[], std::string or CString. If compiler doesn't like caller code, make casting there. std::string should be passed by the way described by Sys_Prog (c_str). CString has i's own const char* operator.
Declaration of ODBCConnection function by such way shows that function gets constant pointer to string, it doesn't change it. You may use also Windows alias for const char*:
void ODBCConnection(LPCSTR szSqlStr)
The following code shows how to cope up if your original string is going to be changed
int main(int argc, char* argv[])
{
UCHAR *ptr ;
string s = "Trial" ;
ptr = new UCHAR [s.size ()+1] ; // allocate sufficient memory
strncpy ( (char * ) ptr, s.c_str(), s.size() ) ; // Copy the data from string to the newly allocated memory
ptr [s.size()+1] = '\0' ; // Null terminate the string
cout << endl << ptr ;
s = "Hello" ; // Modify the original string version
cout << endl << ptr ; // The ptr version unaffected
system("pause");
return 0;
}
Amit
int main(int argc, char* argv[])
{
UCHAR *ptr ;
string s = "Trial" ;
ptr = new UCHAR [s.size ()+1] ; // allocate sufficient memory
strncpy ( (char * ) ptr, s.c_str(), s.size() ) ; // Copy the data from string to the newly allocated memory
ptr [s.size()+1] = '\0' ; // Null terminate the string
cout << endl << ptr ;
s = "Hello" ; // Modify the original string version
cout << endl << ptr ; // The ptr version unaffected
system("pause");
return 0;
}
Amit
ASKER
That first answer was exactly what I needed. The scope of the strings being sent is pretty narrow. Just built with the statements, sent and then go out of scope. Thanks again. Makes my life much easier.
ASKER