So, I got a simple connection to SQL Server, it connects fine, and execute sql fine too, it returns me the first row, but than when it hit the Fetch again it throws this error:
Unhandled exception at 0x011219A0 in JangadaServer.exe: 0xC0000005: Access violation reading location 0x00000008.
code:
bool database::connect()
{
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlenvhandle))
return false;
if (SQL_SUCCESS != SQLSetEnvAttr(sqlenvhandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
return false;
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, sqlenvhandle, &sqlconnectionhandle))
return false;
SQLWCHAR retconstring[1024];
switch (SQLDriverConnect(sqlconnectionhandle,
NULL,
(SQLWCHAR*)TEXT("DRIVER=SQL Server;SERVER=.\\SQLEXPRESS;DATABASE=jangadares;UID=sa;PWD=******;Trusted_Connection=no;"),
SQL_NTS,
retconstring,
1024,
NULL,
SQL_DRIVER_NOPROMPT)){
case SQL_SUCCESS_WITH_INFO:
show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
break;
case SQL_INVALID_HANDLE:
case SQL_ERROR:
show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
return false;
default:
break;
}
return true;
}
bool database::verify_account(char* account, char* password)
{
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, sqlconnectionhandle, &sqlstatementhandle))
return false;
if (SQL_SUCCESS != SQLExecDirect(sqlstatementhandle, (SQLWCHAR*)TEXT("select * from accounts"), SQL_NTS)){
show_error(SQL_HANDLE_STMT, sqlstatementhandle);
return false;
}
else{
char account[50];
char password[50];
int id;
while (SQLFetch(sqlstatementhandle) == SQL_SUCCESS){
SQLGetData(sqlstatementhandle, 1, SQL_C_UBIGINT, &id, 0, NULL);
SQLGetData(sqlstatementhandle, 2, SQL_C_CHAR, account, 50, NULL);
SQLGetData(sqlstatementhandle, 3, SQL_C_CHAR, password, 50, NULL);
std::string acc = account;
acc.erase(remove_if(acc.begin(), acc.end(), isspace), acc.end());
std::string pwd = password;
pwd.erase(remove_if(pwd.begin(), pwd.end(), isspace), pwd.end());
printf("%d", id);
printf(acc.c_str());
printf(pwd.c_str());
}
}
return false;
}
I don't know what to do, since it returns the first row okay, and it only got one row, so I guess I should handle these error or what?
Related
I need to know if the current process is running as system. In C# I use WindowsIdentity.GetCurrent().IsSystem to do that, what is the equivalent in C++?
I'm trying to avoid comparing usernames, because different OS has different usernames for SYSTEM account.
I have created an example based on Eryk's idea, and it works:
BOOL IsSystem()
{
HANDLE hToken = NULL;
BOOL result = false;
TOKEN_USER *tokenUser = NULL;
DWORD dwLength = 0;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) == 0)
{
DbgPrint("OpenProcessToken(): %d", GetLastError());
goto cleanup;
}
if (GetTokenInformation(hToken, TokenUser, (LPVOID) tokenUser, 0, &dwLength) == 0)
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
DbgPrint("GetTokenInformation(): %d", GetLastError());
goto cleanup;
}
tokenUser = (TOKEN_USER *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
if (tokenUser == NULL)
{
goto cleanup;
}
if (GetTokenInformation(hToken, TokenUser, (LPVOID) tokenUser, dwLength, &dwLength) == 0)
{
DbgPrint("GetTokenInformation(): %d", GetLastError());
goto cleanup;
}
result = IsWellKnownSid(tokenUser->User.Sid, WinLocalSystemSid);
}
cleanup:
if (tokenUser != NULL)
{
HeapFree(GetProcessHeap(), NULL, tokenUser);
}
return result;
}
I'm trying to write a C ++ program using a database - IBM DB2 Express-C. Also, I use Visual Studio 2015. Via IBM OLE DB Provider for DB2 my Visual Studio successfully connected to DB2. I can see tables and all OK:
Then I created new C++ program, I successfully connect several header files, some from them I found in my DB2 directory, for example sqlcli1.h
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
#include <sqlcli1.h>
#include <windows.h>
The following is the code of the main program. In which I am trying to connect to the database to which successfully was connected the Visual Studio.
#include "stdafx.h"
int main()
{
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLCHAR * OutConnStr = (SQLCHAR *)malloc(255);
SQLSMALLINT * OutConnStrLen = (SQLSMALLINT *)malloc(255);
// 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) {
// Allocate connection handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// Connect to data source
retcode = SQLConnect(hdbc, (SQLWCHAR*) "DATABASE=SAMPLE;HOSTNAME=localhost", SQL_NTS, (SQLWCHAR*) "db2admin", SQL_NTS, (SQLWCHAR*) "password", SQL_NTS);
if (retcode != SQL_SUCCESS) {
printf(">--- Error while connecting to database:");
printf("SQLConnect: %d\n", retcode);
}
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
printf("\nAllocate Connection handle successfully.");
// Process data
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
system("pause");
return 0;
}
There are no errors at compile time, but can not connect to the database.When program execution comes to the block.
// Connect to data source
retcode = SQLConnect(hdbc, (SQLWCHAR*) "DATABASE=SAMPLE;HOSTNAME=localhost", SQL_NTS, (SQLWCHAR*) "db2admin", SQL_NTS, (SQLWCHAR*) "password", SQL_NTS);
if (retcode != SQL_SUCCESS) {
printf(">--- Error while connecting to database:");
printf("SQLConnect: %d\n", retcode);
}
I see >--- Error while connecting to database:SQLConnect:-2
What does it means? what I am doing is wrong? I also tried it:
retcode = SQLConnect(hdbc, (SQLWCHAR*) "SAMPLE", SQL_NTS, (SQLWCHAR*) "db2admin", SQL_NTS, (SQLWCHAR*) "password", SQL_NTS);
But it also does not work. May be the second argument should look like in some other way?
Changed
I tried use this function SQLGetDiagRec I created some variables
SQLWCHAR SqlState[6], SQLStmt[100], Msg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER NativeError;
SQLSMALLINT i, MsgLen;
SQLRETURN rc1, rc2;
I also change my connect block
// Connect to data source
retcode = SQLConnect(hdbc, (SQLWCHAR*) "SAMPLE", SQL_NTS, (SQLWCHAR*) "db2admin", SQL_NTS, (SQLWCHAR*) "password", SQL_NTS);
if (retcode != SQL_SUCCESS) {
printf(">--- Error while connecting to database:");
printf("SQLConnect: %d\n", retcode);
if ((retcode == SQL_SUCCESS_WITH_INFO) || (retcode == SQL_ERROR)) {
// Get the status records.
i = 1;
while ((rc2 = SQLGetDiagRec(SQL_HANDLE_STMT, hdbc, i, SqlState, &NativeError,
Msg, sizeof(Msg), &MsgLen)) != SQL_NO_DATA) {
cout << SqlState;
cout << i;
cout << NativeError;
cout << Msg;
i++;
}
}
}
But nothing has changed. Does anyone have any idea?
If a call to any CLI function doesn't return SQL_SUCCESS, then your error handling should use SQLGetDiagRec() to get the details of the warning or error.
Documentation: SQLGetDiagRec
I would like to catch an exception, which occures in my code using Try/Catch like this:
try
{
//my code
}
catch(std::exception &e)
{
std::wcout <<"An exception occured"<<" "<<e.what();
}
but such a structure dosn't catch the exception in my code. I recieve an exception from Visual studio in this line:
retcode = bcp_init(hdbc1,"information1", NULL,NULL, DB_IN);
and not from my try/catch.
here you can see my whole code:
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include<tchar.h>
#include<iostream>
#include<sqlncli.h>
#include<exception>
using namespace std;
SQLHENV henv = SQL_NULL_HENV;
HDBC hdbc1 = SQL_NULL_HDBC, hdbc2 = SQL_NULL_HDBC;
SQLHSTMT hstmt2 = SQL_NULL_HSTMT;
void Cleanup() {
if (hstmt2 != SQL_NULL_HSTMT)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
if (hdbc1 != SQL_NULL_HDBC) {
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
}
if (hdbc2 != SQL_NULL_HDBC) {
SQLDisconnect(hdbc2);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
}
if (henv != SQL_NULL_HENV)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
int main() {
try
{
RETCODE retcode;
// BCP variables.
char *terminator = "\0";
// bcp_done takes a different format return code because it returns number of rows bulk copied
// after the last bcp_batch call.
DBINT cRowsDone = 0;
// Set up separate return code for bcp_sendrow so it is not using the same retcode as SQLFetch.
RETCODE SendRet;
// Allocate the ODBC environment and save handle.
retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(Env) Failed\n\n");
Cleanup();
return(9);
}
// Notify ODBC that this is an ODBC 3.0 app.
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLSetEnvAttr(ODBC version) Failed\n\n");
Cleanup();
return(9);
}
// Allocate ODBC connection handle, set bulk copy mode, and connect.
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
retcode = SQLSetConnectAttr(hdbc1, SQL_COPT_SS_BCP, (void *)SQL_BCP_ON, SQL_IS_INTEGER);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLSetConnectAttr(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// sample uses Integrated Security, create the SQL Server DSN using Windows NT authentication
SQLWCHAR dsn[30] = L"mssqltest"; //Name DNS
SQLWCHAR user[10] = L"di_test";
SQLWCHAR pass[10] = L"di_test";
// SQLWCHAR tb[20]=L"information1";
retcode = SQLConnectW(hdbc1, (SQLWCHAR *)dsn, SQL_NTS, (SQLWCHAR *) user, SQL_NTS, (SQLWCHAR *) pass, SQL_NTS);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLConnect() Failed\n\n");
Cleanup();
return(9);
}
// TRYODBC(hdbc1, SQL_HANDLE_DBC, retcode);
// Initialize the bulk copy.
retcode = bcp_init(hdbc1,"information1", NULL,NULL, DB_IN);
/* TRYODBC(hdbc1, SQL_HANDLE_DBC, retcode);*/
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("bcp_init(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
//Define our array
DBINT custIDs[] ={1,2,3,4};
// Bind the program variables for the bulk copy.
if( bcp_bind(hdbc1, (BYTE *)&custIDs, 0, sizeof(DBINT), NULL,0, SQLINT4, 2)==FAIL)
{
retcode=-1;
}
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("bcp_bind(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Could normally use strlen to calculate the bcp_bind cbTerm parameter, but this terminator
// is a null byte (\0), which gives strlen a value of 0. Explicitly give cbTerm a value of 1.
if( bcp_bind(hdbc1,(LPCBYTE) custIDs, 2, SQL_VARLEN_DATA, NULL,0, SQL_C_NUMERIC, 3)==FAIL)
{
retcode=-1;
}
if ( (retcode != SUCCEED) ) {
printf("bcp_bind(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
if ( (SendRet = bcp_sendrow(hdbc1) ) != SUCCEED ) {
printf("bcp_sendrow(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
cRowsDone = bcp_done(hdbc1);
if ( (cRowsDone == -1) ) {
printf("bcp_done(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
printf("Number of rows bulk copied after last bcp_batch call = %d.\n", cRowsDone);
// Cleanup.
SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLDisconnect(hdbc2);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
catch(std::exception &e)
{
std::wcout <<"An exception occured"<<" "<<e.what();
}
}
You're not seeing a C++ exception. This is what Microsoft calls a SEH exception, which is actually a program crash. You can catch those (search on MSDN for __try and __except) but in general this is like the Java NullPointerException - it's a programming error, and no error handling is going to fix that.
Also, Visual Studio, if set to "break on all exceptions", will break when an exception occurs that will be handled in a try/catch too. If you just continue execution, it'll go to the corresponding catch & be handled. If this is what happens, turn off the "break on all exceptions". It will stop anyway on unhandled ones.
C++ is not Java. There is no such thing as a universal base class exception, so std::exception is just a base class for all exceptions thrown by the Standard Library.
If you want to catch any exception (and not any strange error that could happen), you can use catch(...).
As shown by SingerOfTheFall's comment, you can use C++11 std::current_exception to inspect the exception object.
I have the following table defined in MySQL
INSERT INTO routemaster_log (`EntryDateTime`,`Entry`,`Message`,`EntryType`) VALUES (?,?,?,?);
CREATE TABLE `routemaster_log` (
`EntryDateTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`Entry` varchar(127) NOT NULL,
`Message` int(11) NOT NULL DEFAULT '0',
`EntryType` varchar(20) NOT NULL DEFAULT 'INFORMATION'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And the following C++ code to write a record to it
void LogEntries::Insert(string_t LogText, string_t LogType, int MessageNumber)
{
SQLHANDLE hEnv;
SQLRETURN retCode;
SQLCHAR* query;
SQLINTEGER textLength = SQL_NTS;
// now set the text to be written to char *
char* logText = from_string_t(LogText);
char* logType = from_string_t(LogType);
std::string SQLQuery("INSERT INTO routemaster_log (`Entry`,`Message`,`EntryType`) VALUES (?,?,?)");
query = (SQLCHAR *)SQLQuery.c_str();
.
.
.
// log Text
retCode = SQLBindParameter(hStmnt, 1, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_CHAR, 0, 0,
logText, sizeof(logText), &textLength);
if (retCode != SQL_SUCCESS && retCode != SQL_SUCCESS_WITH_INFO) {
std::cout << "SQL Insert failed binding parameters (LogText)" << std::endl;
}
// Message Number
retCode = SQLBindParameter(hStmnt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &MessageNumber, 0, NULL);
if (retCode != SQL_SUCCESS && retCode != SQL_SUCCESS_WITH_INFO) {
std::cout << "SQL Insert failed binding parameters (Message Number)" << std::endl;
}
// Log Type
retCode = SQLBindParameter(hStmnt, 1, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_CHAR, 0, 0,
logType, sizeof(logType), &textLength);
if (retCode != SQL_SUCCESS && retCode != SQL_SUCCESS_WITH_INFO) {
std::cout << "SQL Insert failed binding parameters (LogType)" << std::endl;
}
retCode = SQLExecDirectA(hStmnt, query, SQL_NTS);
if (retCode != SQL_SUCCESS && retCode != SQL_SUCCESS_WITH_INFO)
{
SQLWCHAR Msg[255], SqlState[6];
SQLINTEGER NativeError;
SQLRETURN ret2;
SQLSMALLINT i, MsgLen;
i = 1;
while ((ret2 = SQLGetDiagRec(SQL_HANDLE_STMT, hStmnt, i, SqlState, &NativeError,
Msg, sizeof(Msg), &MsgLen)) != SQL_NO_DATA) {
std::cout << Msg << std::endl;
i++;
}
std::cout << "SQL Insert failed writing data to database." << std::endl;
}
}
everything is fine until the SQLExecDirectA this fails with the SQLBindParameter not used for all parameters error (retrieved in the following while loop).
I would expect this if the number of Parameters being bound was different to the number of '?' in the query but they are the same.
Anyone got a suggestion as to what is wrong?
There is actually two issues with the code in the question.
a) The Calls to SQLBindParameter go before the call to SQLPrepareA
b) In the Calls to SQLBindParameter the second Parameter gives the position of the parameter
The revised code - which works is as follows;
// log Text
retCode = SQLBindParameter(hStmnt, 1, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_CHAR, 0, 0,
logText, sizeof(logText), &textLength);
if (retCode != SQL_SUCCESS && retCode != SQL_SUCCESS_WITH_INFO) {
std::cout << "SQL Insert failed binding parameters (LogText)" << std::endl;
}
// Message Number
retCode = SQLBindParameter(hStmnt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &MsgNumber, 0, NULL);
if (retCode != SQL_SUCCESS && retCode != SQL_SUCCESS_WITH_INFO) {
std::cout << "SQL Insert failed binding parameters (Message Number)" << std::endl;
}
// Log Type
retCode = SQLBindParameter(hStmnt, 3, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_CHAR, 0, 0,
logType, sizeof(logType), &textLength);
if (retCode != SQL_SUCCESS && retCode != SQL_SUCCESS_WITH_INFO) {
std::cout << "SQL Insert failed binding parameters (LogType)" << std::endl;
}
retCode = SQLPrepareA(hStmnt, query, SQL_NTS);
if (retCode != SQL_SUCCESS && retCode != SQL_SUCCESS_WITH_INFO) {
std::cout << "SQL Insert failed preparing statement" << std::endl;
}
retCode = SQLExecDirectA(hStmnt, query, SQL_NTS);
I am building a C++ program that accesss an SQL database. I am able to connect and return values for the following statment:
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT Beta FROM Equity WHERE Ticker = 'AAPL'", SQL_NTS);
However, I would like to be able to replace 'AAPL' with the string 'ticker', which can be defined using cin>>.
Is there any way to do this?
Thanks for the help, the entire code is below:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
#include <string>
using namespace std;
int main(){
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
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, (void*)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);
// Connect to data source
retcode = SQLDriverConnect(
hdbc,
0,
(SQLWCHAR*)L"DSN=Phoenix;SERVER=XXX;UID=XXX;PWD=XXX;DRIVER=MySQL Server;",
_countof(L"DSN=Phoenix;SERVER=XXX;UID=XXX;PWD=XXX;DRIVER=MySQL Server;"),
OutConnStr,
255,
&OutConnStrLen,
SQL_DRIVER_COMPLETE );
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// Process data
string ticker;
cout << " Enter Ticker: "; //Prompt Ticker
cin >> ticker; //Stores Ticker
//retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT Beta FROM Equity WHERE Ticker = 'AAPL'", SQL_NTS);
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT Beta FROM Equity WHERE Ticker = ticker", SQL_NTS);
if (retcode == SQL_SUCCESS) {
SQLINTEGER cbTestStr, iCount = 1;
SQLFLOAT dTestFloat;
SQLCHAR beta[200];
while (TRUE) {
retcode = SQLFetch(hstmt);
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
cout<<"An error occurred";
}
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){
SQLGetData(hstmt, 1, SQL_C_CHAR, beta, 200, &cbTestStr);
/* Print the row of data */
cout<<"Beta for "<< ticker << " = " << beta <<endl;
double bi;
cin >> bi;
} else {
break;
}
}
}else{
cout<<"Query execution error."<<endl;
}
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc);
}else{
cout<<"Connection error"<<endl;
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
system("pause");
return 0;
}
Have you tried something like after your cin >> ticker; line.
string sql;
sql = "SELECT Beta FROM Equity WHERE Ticker='";
strcat (sql,ticker);
strcat (sql, "'");
Then use the sql string in SQLExecDirect line
Replace the statement text with sql.
Sorry my c syntax is rusty. The point is to retrieve ticker value and concatenate that to the sql string while surrounding the input (ticker) with single quotes. Then use this as your execution statement.
Hope it works.