Related
I'm trying to make a class using sqlite3 database with a method that should insert the data in the table when the user adds the files to the application, but it is not working as intended,
void Database::InsertSample(int Favorite, std::string Filename,
std::string SamplePack, int Channels, int Length,
int SampleRate, int Bitrate, std::string Comment,
std::string Path)
{
try
{
rc = sqlite3_open("Samples.db", &DB);
sql = "INSERT INTO SAMPLES (FAVORITE, FILENAME, SAMPLEPACK, CHANNELS, \
LENGTH, SAMPLERATE, BITRATE, BITSPERSAMPLE, PATH) \
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
rc = sqlite3_prepare_v2(DB, sql.c_str(), 0, &stmt, 0); // create the prepared statement
rc = sqlite3_bind_int(stmt, 1, Favorite);
rc = sqlite3_bind_text(stmt, 2, Filename.c_str(), Filename.size(), SQLITE_STATIC);
rc = sqlite3_bind_text(stmt, 3, SamplePack.c_str(), SamplePack.size(), SQLITE_STATIC);
rc = sqlite3_bind_int(stmt, 4, Channels);
rc = sqlite3_bind_text(stmt, 5, Filename.c_str(), Filename.size(), SQLITE_STATIC);
rc = sqlite3_bind_int(stmt, 6, Length);
rc = sqlite3_bind_int(stmt, 7, SampleRate);
rc = sqlite3_bind_int(stmt, 8, Bitrate);
rc = sqlite3_bind_text(stmt, 9, Comment.c_str(), Comment.size(), SQLITE_STATIC);
rc = sqlite3_bind_text(stmt, 10, Path.c_str(), Path.size(), SQLITE_STATIC);
rc = sqlite3_step(stmt);
rc = sqlite3_exec(DB, Sample.c_str(), NULL, 0, &ErrorMessage);
if (rc != SQLITE_OK)
{
std::cerr << "Error! Cannot insert data into table." << std::endl;
sqlite3_free(ErrorMessage);
}
else
{
std::cout << "Data inserted successfully." << std::endl;
}
sqlite3_close(DB);
}
catch (const std::exception &exception)
{
std::cerr << exception.what();
}
}
But this fails, throwing the error statement "Error! Cannot insert data into table.". Am I doing something wrong here.
I'm using this function in another class as,
void Browser::OnClickDirCtrl(wxCommandEvent& event)
{
TagLib::FileRef File (DirCtrl->GetFilePath());
TagLib::String Artist = File.tag()->artist();
TagLib::String Album = File.tag()->album();
TagLib::String Genre = File.tag()->genre();
TagLib::String Title = File.tag()->title();
TagLib::String Comment = File.tag()->comment();
int Bitrate = File.audioProperties()->bitrate();
int Channels = File.audioProperties()->channels();
int Length = File.audioProperties()->lengthInMilliseconds();
int LengthSec = File.audioProperties()->lengthInSeconds();
int SampleRate = File.audioProperties()->sampleRate();
wxVector<wxVariant> Data;
Data.clear();
Data.push_back(false);
Data.push_back(TagLibTowx(Title));
Data.push_back(TagLibTowx(Artist));
Data.push_back(wxString::Format("%d",Channels));
Data.push_back(wxString::Format("%d",LengthSec));
Data.push_back(wxString::Format("%d",SampleRate));
Data.push_back(wxString::Format("%d",Bitrate));
Data.push_back(TagLibTowx(Comment));
SampleListView->AppendItem(Data);
db.InsertSample(0, Title.to8Bit(), Artist.to8Bit(), Channels, Length, SampleRate, Bitrate, Comment.to8Bit(), DirCtrl->GetFilePath().ToStdString());
}
This just a part of the function that should add the files to the database. As you can see, I am storing the path of the files in the database which is important data that I need for the project.
/---------/
EDIT: Adding a short sample,
main.cpp
#include "testdb.hpp"
int main()
{
Database db;
db.InsertData("Hello, World!");
return 0;
}
testdb.hpp
#include <sqlite3.h>
#include <string>
class Database
{
public:
Database();
~Database();
public:
sqlite3* DB;
int rc;
char* ErrorMessage;
std::string Test;
std::string sql;
sqlite3_stmt* stmt;
public:
void InsertData(std::string Path);
};
testdb.cpp
#include <exception>
#include <iostream>
#include <string>
#include "testdb.hpp"
Database::Database()
{
/* Create SQL statement */
Test = "CREATE TABLE TEST("
"TEST TEXT NOT NULL);";
try
{
rc = sqlite3_open("Test.db", &DB);
rc = sqlite3_exec(DB, Test.c_str(), NULL, 0, &ErrorMessage);
if (rc != SQLITE_OK)
{
std::cerr << "Error! Cannot create table." << std::endl;
sqlite3_free(ErrorMessage);
}
else
{
std::cout << "Table created successfuly." << std::endl;
}
sqlite3_close(DB);
}
catch (const std::exception &exception)
{
std::cerr << exception.what();
}
}
void Database::InsertData(std::string Test)
{
try
{
rc = sqlite3_open("Test.db", &DB);
sql = "INSERT INTO TEST (PATH) VALUES (?);";
rc = sqlite3_prepare_v2(DB, sql.c_str(), 10, &stmt, 0); // create the prepared statement
// error handling goes here
rc = sqlite3_bind_text(stmt, 10, Test.c_str(), Test.size(), SQLITE_STATIC);
// error handling goes here
rc = sqlite3_step(stmt);
// error handling goes here
rc = sqlite3_finalize(stmt);
if (rc != SQLITE_OK)
{
std::cerr << "Error! Cannot insert data into table." << std::endl;
sqlite3_free(ErrorMessage);
}
else if (rc == SQLITE_BUSY)
{
std::cout << "BUSY" << std::endl;
}
else if (rc == SQLITE_DONE)
{
std::cout << "DONE" << std::endl;
}
else if (rc == SQLITE_ERROR)
{
std::cout << "ERROR" << std::endl;
}
else if (rc == SQLITE_MISUSE)
{
std::cout << "MISUSE" << std::endl;
}
else
{
std::cout << "Data inserted successfully." << ErrorMessage << std::endl;
}
sqlite3_close(DB);
}
catch (const std::exception &exception)
{
std::cerr << exception.what();
}
}
Database::~Database(){}
Compile using g++ main.cpp testdb.cpp -l sqlite3 -o db.
Same thing happening here, it says data inserted but database shows empty in sqlitebrowser.
You have a sqlite3_step followed by sqlite3_exec, which is probably not what you intended. It's certainly not good. You must call sqlite3_reset or sqlite3_finalize to complete the prepared statement. It will also provide a specific error code that better describes the error if you get one from sqlite3_step.
See this explanation of `sqlite3_step'
I am trying to use sqlite3_prepare_v2() in VC++ but it is giving me error #26 which is "File is not a database." which is confusing because I have opened database successfully.
sqlite3 *testDb;
sqlite3_initialize();
std::string location = uribase+"testDB.sqlite3";
auto rc = sqlite3_open_v2(location.c_str(), &testDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if (rc != SQLITE_OK)
{
logError(rc);
sqlite3_close(testDb);
sqlite3_shutdown();
return -1;
}
else
{
std::cout << "Database opened successfully.";
}
std::string tableName = "test";
std::string strstmt = "SELECT * FROM " + tableName + ";";
sqlite3_stmt *pstmt = NULL;
rc = sqlite3_prepare_v2(testDb, strstmt.c_str(), -1, &pstmt, NULL);
if (rc != SQLITE_OK)
{
logError(rc);
sqlite3_close(testDb);
sqlite3_shutdown();
return -1;
}
Output
SQLite will not access the file until it actually needs to. (And in any case, it would be possible for another application to corrupt the file after it has been opened.)
The problem is that this file indeed is not a database file (or encrypted).
I am using SQLite3 header files in my C++ program and trying to create a table and insert data onto it, it works fine on a regular input.
It shows error when I use it in a C++ loop with changing variables.
I am using the database to insert my reading from RS-232.
Here is my code:
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
std::string sql_str;
std::ostringstream temp;
std::string command;
/* Open database */
rc = sqlite3_open("test_1.db", &db);
if (rc){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}
else{
fprintf(stderr, "Opened database successfully\n");
}
std::string str;
std::ostringstream oss;
oss << id_count; // stornig the primary id int values into a string
str = "INSERT INTO M_DATA (ID, DETAILS) VALUES(";
str += oss.str(); //copying the int primary id
str += ", '";
std::string str_t1(szBuffer); //Copying character aray to a string
str += str_t1; //concatening the string
str += "');";
//printing what the database takes
//output_file << std::endl << str << std::endl;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0
sql = writable;
output_file << std::endl << "## SQL COMMAND : " << sql << "#" << std::endl;
// don't forget to free the string after finished using it
delete[] writable;
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
output_file << std::endl << "** SQL ERROR : " << zErrMsg << "*" << std::endl;
sqlite3_free(zErrMsg);
}
else{
fprintf(stdout, "Records created successfully\n");
}
// _sleep(3000);
sqlite3_close(db);
My issue is I have a szBuffer which changes everytime, and I have to insert it as a new entry into the table.
Is there a way to increment the Primary Key and store my string into it?
The sz buffer at a single line will give data like: For Ex:
szBuffer : ersion = 1 [SPI]: MinorVersion = 2 [SPI]: Real Time
= 1434260351 [SPI]: SR # = SBB-ST1000090
The SQL command in the string I pass is like this:
SQL COMMAND : INSERT INTO M_DATA (ID, DETAILS) VALUES(9,
'ersion = 1 [SPI]: MinorVersion = 2 [SPI]: Real Time = 1434260351
[SPI]: SR # = SBB-ST1000090');
The Error which I get is like:
SQL ERROR : near "¸”_": syntax error
I am not sure if I am doing this right or wrong.
Can we use the insert statement in a loop? Am I passing the string the right way? (It looks correct to me when I print it out.)
But why do I get an error?
Is there any better way to enter my data?
I am very new to this so I tried search the internet, but no one is doing it the way I did it.
Please help.
Many Thanks.
(Almost) never build a SQL statement via string concatenation. Use a prepared statement and bind the parameter values.
// Prepare the statement
sqlite3_stmt* stmt;
int result = sqlite3_prepare_v2(db, "INSERT INTO M_DATA (ID, DETAILS) VALUES(?, ?);", -1, &stmt, nullptr);
// TODO: Handle when result != SQLITE_OK
while(/* whatever you wanted to loop on */)
{
// Bind in the parameter values
result = sqlite3_bind_int(stmt, 1, id_count);
// TODO: Handle when result != SQLITE_OK
result = sqlite3_bind_text(stmt, 2, szBuffer, -1, SQLITE_STATIC);
// TODO: Handle when result != SQLITE_OK
// Invoke the statement
result = sqlite3_step(stmt);
// TODO: Handle when result != SQLITE_OK
// Reset the statement to allow binding variables on the next iteration
result = sqlite3_reset(stmt);
}
// Release the statement
sqlite3_finalize(stmt);
I am trying to save the contents of the key and value of a map into a database table. The .dbo file is created, but nothing goes into the table. It doesn't create table but it doesn't exit. I wonder what is wrong with my code.
void names_table( std::map<std::string, unsigned int> &names ){
std::string sql;
std::string str1;
std::string str2;
std::string str3;
sqlite3_stmt *stmt;
const char *file_names = create_db_file( ); /* default to temp db */
sqlite3 *db;
sqlite3_initialize( );
int rc = sqlite3_open_v2( file_names, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if ( rc != SQLITE_OK) {
sqlite3_close( db );
cout << "Error: Database cannot open!" << endl;
exit( EXIT_FAILURE);
}
sql = "CREATE TABLE IF NOT EXISTS names_table (offset INTEGER PRIMARY KEY, stname TEXT);";
sqlite3_prepare_v2(db, sql.c_str(), sql.size(), &stmt, NULL);
if (sqlite3_step(stmt) != SQLITE_DONE) cout << "Didn't Create Table!" << endl;
for (auto pm = names.begin(); pm != names.end(); pm++) {
str2 = "'" + pm->first + "'";
char tmp[15];
sprintf(tmp,"%u",pm->second);
str3 = tmp;
str1 = (((("INSERT INTO names_table VALUES(" + str3) + ", ") + str2) + ");");
std::cout << str1 << std::endl;
sql = (char *)str1.c_str();
// stmt = NULL;
rc = sqlite3_prepare_v2(db, sql.c_str(), sql.size(), &stmt, NULL);
if ( rc != SQLITE_OK) {
sqlite3_close(db);
cout << "Error: Data cannot be inserted!" << endl;
exit ( EXIT_FAILURE);
}
}
sqlite3_close( db );
}
INSERT INTO names_table VALUES(ramsar, 8329) - I hope you're aware that string literals in SQL need to be enclosed in quotes. Try this: INSERT INTO names_table VALUES('ramsar', 8329).
EDIT: Actually, your code will never do what you want, because you're not even calling sqlite3_step after sqlite3_prepare_v2, which means that you're only compiling your SQL statement, but never evaluating it. Where did you find this bad example? See here and here decent examples on how to use the SQLite C++ interface properly.
PS: Stop messing around with sprintf in C++. You have std::stringstream for it.
I am trying to create a database in c++ using sqlite3 lib.. I am getting error sqlite3_prepare_v2'
was not declared in this scope as shown in logcat.
log file
..\src\Test.cpp: In function 'int main(int, const char**)':
..\src\Test.cpp:21:85: error: 'sqlite3_prepare_v2' was not declared in this scope
..\src\Test.cpp:30:13: error: variable 'sqlite3 in' has initializer but incomplete type
..\src\Test.cpp:30:30: error: invalid use of incomplete type 'sqlite3 {aka struct sqlite3}'
..\src\/sqlite3.h:73:16: error: forward declaration of 'sqlite3 {aka struct sqlite3}'
Here is my code
#include <iostream>
using namespace std;
#include "sqlite3.h"
int main (int argc, const char * argv[]) {
sqlite3 *db;
sqlite3_open("test.db", & db);
string createQuery = "CREATE TABLE IF NOT EXISTS items (busid INTEGER PRIMARY KEY, ipaddr TEXT, time TEXT NOT NULL DEFAULT (NOW()));";
sqlite3_stmt *createStmt;
cout << "Creating Table Statement" << endl;
sqlite3_prepare_v2(db, createQuery.c_str(), createQuery.size(), &createStmt, NULL);
cout << "Stepping Table Statement" << endl;
if (sqlite3_step(createStmt) != SQLITE_DONE) cout << "Didn't Create Table!" << endl;
string insertQuery = "INSERT INTO items (time, ipaddr) VALUES ('test', '192.168.1.1');"; // WORKS!
sqlite3_stmt *insertStmt;
cout << "Creating Insert Statement" << endl;
sqlite3_prepare(db, insertQuery.c_str(), insertQuery.size(), &insertStmt, NULL);
cout << "Stepping Insert Statement" << endl;
if (sqlite3_step(insertStmt) != SQLITE_DONE) cout << "Didn't Insert Item!" << endl;
cout << "Success!" << endl;
return 0;
}
please help me out. thanks.....
#include <sqlite3.h>
should contain sqlite3_prepare_v2 and struct sqlite3. Make sure you're including the right sqlite3.h file.
Also in sqlite3_prepare_v2 the 3rd arg can be (and should be in your case) -1 so the sql is read to the first null terminator.
Working bare-metal sample using sqlite 3.7.11:
#include <sqlite3.h>
int test()
{
sqlite3* pDb = NULL;
sqlite3_stmt* query = NULL;
int ret = 0;
do // avoid nested if's
{
// initialize engine
if (SQLITE_OK != (ret = sqlite3_initialize()))
{
printf("Failed to initialize library: %d\n", ret);
break;
}
// open connection to a DB
if (SQLITE_OK != (ret = sqlite3_open_v2("test.db", &pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)))
{
printf("Failed to open conn: %d\n", ret);
break;
}
// prepare the statement
if (SQLITE_OK != (ret = sqlite3_prepare_v2(pDb, "SELECT 2012", -1, &query, NULL)))
{
printf("Failed to prepare insert: %d, %s\n", ret, sqlite3_errmsg(pDb));
break;
}
// step to 1st row of data
if (SQLITE_ROW != (ret = sqlite3_step(query))) // see documentation, this can return more values as success
{
printf("Failed to step: %d, %s\n", ret, sqlite3_errmsg(pDb));
break;
}
// ... and print the value of column 0 (expect 2012 here)
printf("Value from sqlite: %s", sqlite3_column_text(query, 0));
} while (false);
// cleanup
if (NULL != query) sqlite3_finalize(query);
if (NULL != pDb) sqlite3_close(pDb);
sqlite3_shutdown();
return ret;
}
Hope this helps
Guys , creating database using sqlite3 in c/c++, here I'm using follwing steps...
1) Firstly you include MinGw file .
2) Add header file sqlite3.h, sqlite3.c in your src folder.
3) Add libr folder , in libr here include these file
mysqlite.h, shell.c, sqlite3.c, sqlite3.h, sqlite3ext.h
After then start your coding...
#include <iostream>
using namespace std;
#include "sqlite3.h"
int main (int argc, const char * argv[]) {
sqlite3 *db;
sqlite3_open("test1.db", & db);
string createQuery = "CREATE TABLE IF NOT EXISTS items (userid INTEGER PRIMARY KEY, ipaddr
TEXT,username TEXT,useradd TEXT,userphone INTEGER,age INTEGER, "
"time TEXT NOT NULL DEFAULT
(NOW()));";
sqlite3_stmt *createStmt;
cout << "Creating Table Statement" << endl;
sqlite3_prepare(db, createQuery.c_str(), createQuery.size(), &createStmt, NULL);
cout << "Stepping Table Statement" << endl;
if (sqlite3_step(createStmt) != SQLITE_DONE) cout << "Didn't Create Table!" << endl;
string insertQuery = "INSERT INTO items (time, ipaddr,username,useradd,userphone,age)
VALUES ('7:30', '192.187.27.55','vivekanand','kolkatta','04456823948',74);"; // WORKS!
sqlite3_stmt *insertStmt;
cout << "Creating Insert Statement" << endl;
sqlite3_prepare(db, insertQuery.c_str(), insertQuery.size(), &insertStmt, NULL);
cout << "Stepping Insert Statement" << endl;
if (sqlite3_step(insertStmt) != SQLITE_DONE) cout << "Didn't Insert Item!" << endl;
return 0;
}
go through this link. I am not sure. It might help you out.
I think their is no sqlite3_prepare_v2 in sqlite3.h lib, so try this.. sqlite3_prepare_v2 can be replaced by sqlite3_prepare, but more care is needed, because it changes the semantics of subsequent calls slightly.