error when compiling the sqlite documentation code - c++

I copied this code
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
int i;
for (i = 0; i<argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[]) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
/* Open database */
rc = sqlite3_open("test.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}
else {
fprintf(stdout, "Opened database successfully\n");
}
/* Create SQL statement */
sql = "CREATE TABLE COMPANY(" \
"ID INT PRIMARY KEY NOT NULL," \
"NAME TEXT NOT NULL," \
"AGE INT NOT NULL," \
"ADDRESS CHAR(50)," \
"SALARY REAL );";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else {
fprintf(stdout, "Table created successfully\n");
}
sqlite3_close(db);
return 0;
}
from official documentation sqlite here: https://www.tutorialspoint.com/sqlite/sqlite_c_cpp.htm
and I got error like this:
Error C2440 '=': cannot convert from 'const char [164]' to 'char *'
I'm using visual studio 2017 and compile file .cpp. I guess something can be wrong with connection between .c and .cpp files, because sqlite is written in .c

The issue is that you are using old C-style variable declaration (all at the beginning) in C++ with the wrong types.
Use this instead:
const char* sql = "CREATE TABLE COMPANY(" \
"ID INT PRIMARY KEY NOT NULL," \
"NAME TEXT NOT NULL," \
"AGE INT NOT NULL," \
"ADDRESS CHAR(50)," \
"SALARY REAL );";
Literal char* are const in C++11.

Related

formatting sqlite3_exec result

Hello how would I go about formatting the result of
sql = "SELECT * from COMPANY ORDER BY ID";
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
I read there are console commands for it on here https://www.tutorialspoint.com/sqlite/sqlite_commands.htm
so I tried
std::string c3 = "sqlite>.header on";
std::string c1 = "sqlite>.mode column";
cout << system(c3.c_str()) << endl;
cout << system(c1.c_str()) << endl;
but that didn't work to get a table format like result
How would I do this? I've been googling for 3 hours and still didn't get anywhere
You can't control the formatting from the sqlite3 user program, so using system() to call it will not control the C API.
You should do this using the callback function. From the same tutorialpoint site:
static int callback(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: ", (const char*)data);
for(i = 0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}

error C2440: 'initializing' : cannot convert from

While using SQLite in C++98, how to convert stringstream to Unicode and pass it to sqlite3_exec()? I constantly have this error:
error C2440: 'initializing' : cannot convert from 'std::basic_string<_Elem,_Traits,_Ax>' to 'std::basic_string<_Elem,_Traits,_Ax>'
1> with"
Code:
int main(int argc, char* argv[]) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
tstringstream tstrsSQL;
tstrsSQL.imbue(std::locale("C"));
std::string s = tstrsSQL.str(); // converting stringstream to char?
const char* p = s.c_str();
/* Open database */
rc = sqlite3_open("db.db3", &db);
if( rc ) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
} else {
fprintf(stderr, "Opened database successfully\n");
}
/* Create SQL statement */
tstrsSQL << _T("SELECT") something ("FROM") << table;
/* Execute SQL statement */
rc = sqlite3_exec(db, p, callback, (void*)data, &zErrMsg); // p needs to be unicode
You are using tstringstream, which I guess uses std::wstringstream if UNICODE is defined, so its str() gives a std::basic_string<wchar_t>.
But you get the result into a std::string, which is std::basic_string<char>. So the assignment fails.
Anyway, you take the result and use it in sqlite3_exec(), which takes a const char* as input.
That's why you shouldn't use tstringstream, you should use std::stringstream, and remove the _T from all of the string literals.
Minimal, complete, working code:
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
stringstream strstream;
strstream << "Hello World";
string str = strstream.str();
cout << str << endl;
return 0;
}

C++ SQLite3 query issue unsolved

I'm somewhat new to SQL and C++. I do believe the question I have yields a simple solution.
I have to create a sql query to insert some values into an existing table (const char *sql_query), with mixed strings and float values. My issue is getting the string assembly operation nailed down, without getting compiler errors.
Here is my attempt:
int main(int argc, char* argv[])
{
create_entry("mahut", "topa", "suma", 5.55, 6.66, 7.77);
return 0;
}
void create_entry(char col1[], char col2[], char col3[], float col4, float col5, float col6)
{
cout << ("create_entry") << endl;
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
char db_name[] = "db_test.db";
stringstream sql_query;
// assemble string
sql_query << "INSERT INTO Department1 (Date,Time,Accept,Factor1,Factor2,Factor3) VALUES ('" << col1 << "','" << col2 << "','" << col3 << "','" << col4 << "','" << col5 << "','" << col6 << "')";
string str = sql_query.str();
rc = sqlite3_open(db_name, &db);
if( rc )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
}
else
{
fprintf(stderr, "Opened database successfully\n");
}
// execute SQL statement
rc = sqlite3_exec(db, str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK )
{
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else
{
fprintf(stdout, "Records created successfully\n");
}
sqlite3_close(db);
}
static int callback(void *db, int argc, char **argv, char **azColName)
{
cout << "Debug <in callback>" << endl;
for(int i=0; i<argc; ++i)
{
//printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
cout << ("%s", argv[i] ? argv[i] : "NULL") << endl;
}
tbl_exists = true;
return 0;
}
Particularly this is my problem:
sql_query << "INSERT INTO Department1 (Date,Time,Accept,Factor1,Factor2,Factor3) VALUES ('" << col1 << "','" << col2 << "','" << col3 << "','" << col4 << "','" << col5 << "','" << col6 << "')";
As I don't understand if there is a proper way to mix in float, integer and string into const char *
I'm not sure what's wrong, but like I said I have tried it for quite some time to properly assemble that string but have failed, as I just don't grasp pointers and strings in C++. Compiling fails due to following error
error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const char*’ for argument ‘2’ to ‘int sqlite3_exec(sqlite3*, const char*, int (*)(void*, int, char**, char**), void*, char**)’ rc = sqlite3_exec(db, str, callback, 0, &zErrMsg);
I also get the following warning
warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
For your error, you're missing a .c_str() conversion of the std::string to a C-style string. sqlite3_exec takes C-style const char * strings, not C++ strings.
For your warning, you'll need to declare your parameters to create_entry() as const char * (or const char []) - because they're literals (constants that should not be modified). Declaring them non-const opens you up to accidentally modifying them.
Assembling the string becomes easier if you are not doing it at all:
void create_entry(const char col1[], const char col2[], const char col3[],
float col4, float col5, float col6)
{
sqlite3 *db;
int rc;
const char *sql;
static const char db_name[] = "db_test.db";
sqlite3_stmt *stmt;
sql = "INSERT INTO Department1 (Date,Time,Accept,Factor1,Factor2,Factor3)"
" VALUES (?,?,?,?,?,?)";
rc = sqlite3_open(db_name, &db);
if( rc != SQLITE_OK )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return;
}
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if( rc != SQLITE_OK )
{
fprintf(stderr, "Can't prepare query: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return;
}
sqlite3_bind_text(stmt, 1, col1, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, col2, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, col3, -1, SQLITE_STATIC);
sqlite3_bind_double(stmt, 4, col4);
sqlite3_bind_double(stmt, 5, col5);
sqlite3_bind_double(stmt, 6, col6);
rc = sqlite3_step(stmt);
if( rc != SQLITE_DONE )
{
fprintf(stderr, "Can't execute query: %s\n", sqlite3_errmsg(db));
sqlite3_finalize(stmt);
sqlite3_close(db);
return;
}
sqlite3_finalize(stmt);
sqlite3_close(db);
}

INSERT INTO command in SQLite with C++ doesnt work

I have a problem with an INSERT INTO command using SQLite3 in C++.
I want to save different strings in an existing database.
I already tested it with static values. There it works fine.
But when I want to save generated strings in that database, the database is empty every time.
Thats my c++ code:
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string>
#include <sstream>
#include "createdb.h"
using namespace std;
/* Converts Strings into quotes */
string quotesql( const string& s ) {
return string("'") + s + string("'");
}
double addquery(string name, string email, double temp, double humidy, double intervall)
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql_insert;
double i = 1;
/* Convert Double into String */
stringstream NumberString;
NumberString << temp;
string stringtemp = NumberString.str();
NumberString << humidy;
string stringhumidy = NumberString.str();
NumberString << intervall;
string stringintervall = NumberString.str();
NumberString << i;
string stringi = NumberString.str();
string stringname = name;
string stringemail = email;
/* Open database */
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/* This INSERT INTO command works fine
sql_insert = "INSERT INTO einstellungen (ID,EMAIL,NAME,TEMP,INTERVALL,HUMIDY)" \
"VALUES (1, 'user#test.com', 'John Doe', -5, 50, 20 );"; */
/*
/* This INSERT INTO command doesn't work */
string sqlstatement =
"INSERT INTO einstellungen (ID, EMAIL, NAME, TEMP, INTERVALL, HUMIDY) VALUES ("
+ quotesql(stringi) + ","
+ quotesql(stringemail) + ","
+ quotesql(stringname) + ","
+ quotesql(stringtemp) + ","
+ quotesql(stringintervall) + ","
+ quotesql(stringhumidy) + ");";
*/
/* Execute SQL statement */
rc = sqlite3_exec(db, sql_insert, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Einstellungen gespeichert\n");
}
sqlite3_close(db);
return 0;
}
Does anybody know where I make a mistake?
Thanks a lot :-)
I create some cout commands after each string command.
Here is the result:
I build some cout commands between each string command:
Here the result:
Datenbank wird nun angelegt
Datenbank erfolgreich angelegt
Datenbank erfolgreich initalisiert
Stringtemp: -5
Strinhumidy: 25
Stringintervall: 500
Stringi: 1
Stringname: John Doe
Stringemail: john.doe#online.de
Opened database successfully
INSERT INTO einstellungen (ID,EMAIL,NAME,TEMP,INTERVALL,HUMIDY)VALUES
(1,'john.doe#online.de','John Doe',-5,500,25);
Einstellungen gespeichert
Your numerical values such as stringhumidy shouldn't be enclosed in quotes. If you still have a problem then print somewhere the value of the sqlstatement in order to find what the error is.
I found my mistake!
I added the following line:
char * buffer = new char[sqlstatement.length()];
strcpy(buffer,sqlstatement.c_str());
So i converted the sqlstatement (string) into the required char operator

comparing the results with user input - sqlite3 c++

I have a table(Item) with attribute of id,item
id|itemName
1|noodle
2|burger
Basically I would like to ask is there anyway that I can compare a input results against my database
record?
e.g if I input noodle and there's is a matching record "noodle" in my in my database it will return found;
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
const char *sql;
std::string itemName;
rc = sqlite3_open("test.db", &db);
if( rc ) {
// failed
fprintf(stderr, "Can't open database: %s\n",
sqlite3_errmsg(db));
}
else
{
// success
fprintf(stderr, "Open database successfully\n");
}
std::cout << "Enter a Item" << std::endl;
std::cin >> itemName;
sql = "select * from Item";
rc = sqlite3_exec(db,sql, callback, 0, &zErrMsg);
if(//how do I compare the itemName from my database against the user input)
{
}
sqlite3_close(db);
return 0;
}
Instead of a callback you can use a parameter to specify just the record you need:
std::cin >> itemName;
sql = "select id from Item where itemName = ?";
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
// set the ? parameter to the itemname you are looking for:
sqlite3_bind_text(stmt, 1, itemName.c_str(), -1, SQLITE_TRANSIENT);
if(sqlite3_step(stmt) == SQLITE_ROW )
{
int id=sqlite3_column_int(stmt,0);
std::cout << "Found id=" << id << std::endl;
}
sqlite3_finalize(stmt);
sqlite3_close(db);