Dynamic SQL Query with C++ - c++

Im working on a program that are accessing a SQL server.
I've established the connection, and i can get the stand i want, but only when my SQL Query is static.
I've read a post in here, where the same question was asked, tried his solution, which sadly didn't work (8 years old post also).
The function used to gain the Query is the following:
SQLWCHAR ConstructQuery()
{
wstring temp = L"SELECT Something FROM somewhere WHERE condition";
SQLWCHAR statement = (SQLWCHAR)temp.c_str();
return statement;
}
and my code for running this query is as follows:
SQLStatement = ConstructQuery();
SQLExecDirect(sqlStmtHandle,&SQLStatement, SQL_NTS))
SQLCHAR sqldata[SQL_RESULT_LEN];
SQLINTEGER ptrsqldata;
while (SQLFetch(sqlStmtHandle) == SQL_SUCCESS) {
SQLGetData(sqlStmtHandle, 1, SQL_CHAR, sqldata, SQL_RESULT_LEN, &ptrsqldata);
//display query result
cout << "\nQuery Result:\n\n";
cout << sqldata << endl;
}
The code runs, but i dont get any output.
Does anyone has any advice ? :-)

Related

How to get data from a specific data piece from a JSON

I'm trying to get the first accepted_answer_id.
If i print out the parsed data this is what it looks like
{"items":[{"accepted_answer_id":23249538,"question_id":23248046},{"accepted_answer_id":5582009,"question_id":5581697},{"accepted_answer_id":43114369,"question_id":43113569},{"accepted_answer_id":12120575,"question_id":12120425},{"question_id":22162858},{"accepted_answer_id":10101621,"question_id":10101556}]}
what I want is that first accepted_answer_id's numbers. So in this case all I want is 23249538. How would I go about doing this? I'm doing this using stack exchange API. This is for an assignment for school where I have to set up on our server a tool that when people ask a question gets them if available someones answer from stack overflow. This number will piped into another URL using CURL which will then grab the answer for me and print it to terminal for the user. I also want it that if there is no accepted_answer_id it just terminates the program with a failure to find answer to user.
//actually getting the data
result = curl_easy_perform(curl);
//making sure that the curl is ok and worked right
if(result != CURLE_OK)
{
cout << curl_easy_strerror(result) << endl;
return 1;
}
//making sure that the website gave info
int httpCode(0);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
curl_easy_cleanup(curl);
//if website worked it will be equal to 200
if(httpCode == 200)
{
cout << "Sucessful Response From URL" << endl;
json data = json::parse(readBuffer);
cout << data << endl;
}
}
You can use a json lib for CPP, such as rapidjson (rapidjson is faster)or jsoncpp, etc.
https://github.com/Tencent/rapidjson
https://github.com/open-source-parsers/jsoncpp

SQLExecDirect command is not working same queries

I'm working Visual Studio 2017 and SQL Server 2017 .
I want to do is create a query with C ++ and that will run it on SQL Server.
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"SELECT ##VERSION", SQL_NTS)) {
cout << "Database Already Exits or Cannot Created";
cout << "\n";
goto COMPLETED;
}
else {
cout << "Success !!!";
cout << "\n";
}
I use this sample : https://www.techhowtos.com/programming/how-to-connect-to-sql-server-from-visual-c-plus-plus/
But ,
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"SELECT ##VERSION", SQL_NTS))
on this line , if i'm write
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"**USE database_name**", SQL_NTS))
or
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"**SELECT * FROM sampletable**", SQL_NTS))
or
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"INSERT INTO sampletable (one,two,three) VALUES (1,2,3)", SQL_NTS))
this query is not working .
But ,
if i'm running this queries (some sample) ;
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"**CREATE DATABASE blablabla**", SQL_NTS))
or
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"**DELETE DATABASE blablabla**", SQL_NTS))
Queries are working .
i have a 2 function
void run_query(string query);
void create_query();
create query function working is normally . generate a query and this query goes to run_query .
What should I do in the run_query() function so that every created query works?
My all codes in here : https://paste.laravel.io/7c693fdb-2dc9-41cc-b183-6e45fd3d9b6d
Thanks for everything :)
SQLExecDirect can return values besides SQL_SUCCESS when the statement succeeds. For example, USE will normally return SQL_SUCCESS_WITH_INFO to indicate the statement succeeded and that informational/warning messages ("changed database context") were returned. Messages can be retrieved with SQLGetDiagRec if desired.
I suggest you consider at least all the "happy path" ODBC function call return values and handle each appropriately, raising an exception with diagnostic information when an unexpected value is returned.

C++ SQLExecDirect INSERT doesn't work

I've wrote a simple SQL C++ Wrapper-Class, where I encountered a real strange Problem. When I call an INSERT-Command with SQLExecDirect, the data does not appear in the SQL Database (SQL Server 2012), although SQLRowCount returns one row. The table, which I'm trying to write to, is named "Person" and has four columns (ID (AUTOINCREMENT), Firstname (nvarchar(100)), Lastname (nvarchar(100)), Birthday (date))
Here is my code:
Class-Constructor (EnvHandle, DBCHandle and StmtHandle are class-members)
SQLDatabase::SQLDatabase()
{
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &EnvHandle);
SQLSetEnvAttr(EnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, EnvHandle, &DBCHandle);
SQLSetConnectAttr(DBCHandle, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);
}
Query-Member-Function
int SQLDatabase::ExecuteNonQuery(std::wstring Command)
{
SQLRETURN RetCode = -1;
SQLINTEGER RowCount = 0;
SQLAllocHandle(SQL_HANDLE_STMT, DBCHandle, &StmtHandle);
RetCode = SQLExecDirect(StmtHandle, (SQLWCHAR*)Command.c_str(), Command.length());
if (RetCode == SQL_SUCCESS || RetCode == SQL_SUCCESS_WITH_INFO)
{
SQLRowCount(StmtHandle, &RowCount);
SQLFreeHandle(SQL_HANDLE_STMT, StmtHandle);
return RowCount;
}
else
{
SQLFreeHandle(SQL_HANDLE_STMT, StmtHandle);
return -1;
}
}
Function-Call in main.cpp
wcout << "Firstname:\n>";
wcin >> Firstname;
wcout << "Lastname:\n>";
wcin >> Lastname;
wcout << "Birthday:\n>";
wcin >> Birthday;
InsRows = database.ExecuteNonQuery(L"INSERT INTO Person (Firstname,Lastname,Birthday) VALUES ('" + Firstname + L"','" + Lastname + L"','" + Birthday + L"')");
if (InsRows == -1)
database.Error();
else
std::wcout << InsRows << " rows affected!" << std::endl;
As already said, "database.ExecuteNonQuery" returns one row.
When take a look at the table in SQL Management Studio, the datarow hasn't been added. I've already traced the queries on the table. The query appears in the tracelog correctly without any additional info. My IDE is Visual Studio 2013.
Any ideas how I could get the data into the table?
Thanks!
Sebastian
In general, whenever a query is executed that changes a table (without error) and the results are not shown, this means that the changes were not committed.
Looking at your code, you have this:
SQLSetConnectAttr(DBCHandle, SQL_ATTR_AUTOCOMMIT,
(SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);}
You set the connection attribute to have auto commit turned off. Either specify you want auto commit on, or issue a call to SQLEndTran to commit the changes.
You're using SQL_AUTOCOMMIT_OFF, which means your statements won't be automatically committed, so your new record is visible only in your transaction and will never be committed in the database. Try to use the auto-commit feature of the MS SQL Server (setting SQL_ATTR_AUTOCOMMIT to SQL_AUTOCOMMIT_ON or just leave it uninformed since it's the default behaviour) or explicitly begin and commit your transaction.
http://msdn.microsoft.com/en-us/library/ms713605(v=vs.85).aspx

sqlite - delete and get all values of some column from affected rows [duplicate]

I heard of using sqlite3_prepare_v2 instead of sqlite_exec to get integers from database, but I failed to find any examples. This page wasn't helpful also. Now I am getting strings from database, so I need to parse them with atoi and this seems to be slow and ineffective.
There a lot of similar questions on SO, but they are about obj-c and iOS SDK. I need C/C++ hint or example.
Thanks in advance.
After sqlite3_prepare has succeeded, you must not forget to clean up the statement with sqlite3_finalize.
To get the result records, call sqlite3_step until it does not return SQLITE_ROW.
To get the values of the current result record, call the sqlite3_column_* functions:
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db, "SELECT 42", -1, &stmt, NULL) != SQLITE_OK)
...error...
else {
for (;;) {
int rc = sqlite3_step(stmt);
if (rc == SQLITE_DONE)
break;
if (rc != SQLITE_ROW) {
...error...
break;
}
printf("value: %d\n", sqlite3_column_int(stmt, 0));
}
sqlite3_finalize(stmt);
}
sqlite3_column_int(result, columnNum); will return one column from the current row of your result as an int.
Your prepare function is to prepare your query, it has nothing to do with how the results are interpreted. All data in sqlite3 is stored textually, you use the appropriate function to retrieve a value in the type you believe it should be.

Getting int values from SQLite

I heard of using sqlite3_prepare_v2 instead of sqlite_exec to get integers from database, but I failed to find any examples. This page wasn't helpful also. Now I am getting strings from database, so I need to parse them with atoi and this seems to be slow and ineffective.
There a lot of similar questions on SO, but they are about obj-c and iOS SDK. I need C/C++ hint or example.
Thanks in advance.
After sqlite3_prepare has succeeded, you must not forget to clean up the statement with sqlite3_finalize.
To get the result records, call sqlite3_step until it does not return SQLITE_ROW.
To get the values of the current result record, call the sqlite3_column_* functions:
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db, "SELECT 42", -1, &stmt, NULL) != SQLITE_OK)
...error...
else {
for (;;) {
int rc = sqlite3_step(stmt);
if (rc == SQLITE_DONE)
break;
if (rc != SQLITE_ROW) {
...error...
break;
}
printf("value: %d\n", sqlite3_column_int(stmt, 0));
}
sqlite3_finalize(stmt);
}
sqlite3_column_int(result, columnNum); will return one column from the current row of your result as an int.
Your prepare function is to prepare your query, it has nothing to do with how the results are interpreted. All data in sqlite3 is stored textually, you use the appropriate function to retrieve a value in the type you believe it should be.