Related
I don't have problem inserting UTF-8 (korean character in my case) using direct sql command in PGAdmin or psql console. But when I need to insert values in C++ by using libpq library, I got the encoding error and I couldn't resolve it until now.
I have tested DB connection, etc and works well. So I will just share the insertion code only :
/* INSERT demo */
res = PQexec(conn,
"insert into db_test values('testval', '군포지사','N00225','영동선','0500','E',13.67,14.18);");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
std::cout << "Insert into table failed: " << PQresultErrorMessage(res)
<< std::endl;
}
else
std::cout << "inserted" << std::endl;
PQclear(res);
Below is the error :
Insert into table failed: ERROR: invalid byte sequence for encoding "UTF8": 0xb1
I have managed to solve it, sorry for my lack of understanding in encoding processing. I just need to convert ANSI to UTF-8, below is my working code. If there's a better solution, please post your answer.
int AnsiToUTF8(char* szSrc, char* strDest, int destSize)
{
WCHAR szUnicode[255];
char szUTF8code[255];
int nUnicodeSize = MultiByteToWideChar(CP_ACP, 0, szSrc, (int)strlen(szSrc), szUnicode, sizeof(szUnicode));
int nUTF8codeSize = WideCharToMultiByte(CP_UTF8, 0, szUnicode, nUnicodeSize, szUTF8code, sizeof(szUTF8code), NULL, NULL);
assert(destSize > nUTF8codeSize);
memcpy(strDest, szUTF8code, nUTF8codeSize);
strDest[nUTF8codeSize] = 0;
return nUTF8codeSize;
}
/* INSERT demo */
char queryUtf8[100];
std::string queryAnsi = "insert into db_test values('testval', '군포지사','N00225','영동선','0500','E',13.67,14.18);";
AnsiToUTF8(&queryAnsi[0u], queryUtf8, 100);
res = PQexec(conn, queryUtf8);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
std::cout << "Insert into table failed: " << PQresultErrorMessage(res)
<< std::endl;
}
else
std::cout << "inserted" << std::endl;
PQclear(res);
The proper solution is to set the client_encoding parameter to the correct value (the encoding your client uses). You can do that when connecting to the database:
PGconn *conn;
conn = PQconnectdb("user=carl password=secret client_encoding=LATIN1");
I'm very new to C++. just created a C++ Windows Forms project using Visual Studio Community 2015. And used the below main function to obtain a SQL connection.
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <sql.h>
using namespace std;
int main()
{
#define SQL_RESULT_LEN 240
#define SQL_RETURN_CODE_LEN 1000
//define handles and variables
SQLHANDLE sqlConnHandle;
SQLHANDLE sqlStmtHandle;
SQLHANDLE sqlEnvHandle;
SQLWCHAR retconstring[SQL_RETURN_CODE_LEN];
//initializations
sqlConnHandle = NULL;
sqlStmtHandle = NULL;
//allocations
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlEnvHandle))
goto COMPLETED;
if (SQL_SUCCESS != SQLSetEnvAttr(sqlEnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
goto COMPLETED;
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, sqlEnvHandle, &sqlConnHandle))
goto COMPLETED;
//output
cout << "Attempting connection to SQL Server...";
cout << "\n";
//connect to SQL Server
switch (SQLDriverConnect(sqlConnHandle,
NULL,
(SQLWCHAR*)L"Server=P2005\SQLEXPRESS2014;Database=CPPDB;User Id=myuid;Password=mypswd;",
SQL_NTS,
retconstring,
1024,
NULL,
SQL_DRIVER_NOPROMPT)) {
case SQL_SUCCESS:
cout << "Successfully connected to SQL Server";
cout << "\n";
break;
case SQL_SUCCESS_WITH_INFO:
cout << "Successfully connected to SQL Server";
cout << "\n";
break;
case SQL_INVALID_HANDLE:
cout << "Could not connect to SQL Server";
cout << "\n";
goto COMPLETED;
case SQL_ERROR:
cout << "Could not connect to SQL Server";
cout << "\n";
goto COMPLETED;
default:
break;
}
//if there is a problem connecting then exit application
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, sqlConnHandle, &sqlStmtHandle))
goto COMPLETED;
//output
cout << "\n";
cout << "Executing T-SQL query...";
cout << "\n";
//if there is a problem executing the query then exit application
//else display query result
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"SELECT ##VERSION", SQL_NTS)) {
cout << "Error querying SQL Server";
cout << "\n";
goto COMPLETED;
}
else {
//declare output variable and pointer
SQLCHAR sqlVersion[SQL_RESULT_LEN];
SQLINTEGER ptrSqlVersion;
while (SQLFetch(sqlStmtHandle) == SQL_SUCCESS) {
SQLGetData(sqlStmtHandle, 1, SQL_CHAR, sqlVersion, SQL_RESULT_LEN, &ptrSqlVersion);
//display query result
cout << "\nQuery Result:\n\n";
cout << sqlVersion << endl;
}
}
//close connection and free resources
COMPLETED:
SQLFreeHandle(SQL_HANDLE_STMT, sqlStmtHandle);
SQLDisconnect(sqlConnHandle);
SQLFreeHandle(SQL_HANDLE_DBC, sqlConnHandle);
SQLFreeHandle(SQL_HANDLE_ENV, sqlEnvHandle);
//pause the console window - exit when key is pressed
cout << "\nPress any key to exit...";
getchar();
return 0;
}
When I build and run the above code, It always gives "Could not connect to SQL Server".
SQL connection string is given below as,
"Server=P2005\SQLEXPRESS2014;Database=CPPDB;User Id=myuid;Password=mypswd;"
I got the above connection string format from this link.
And I'm using Microsoft SQL Server 2014 via SQL Management Studio.
Note : It always triggers the SQL_ERROR case in switch.
I'm trying to trace the error. But I didn't get any luck.
Why this occurs?
Any help would be appreciated.
Thanks.
This is a suggestion.
Try Visual C++ MFC Template.
Include belows.
//For CDatabase class
#include "odbcinst.h"
#include "afxdb.h"
//
Do below stuff anywhere you want.
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = L"ODBC Driver 11 for SQL Server";
CString sDsn;
int iRec = 0;
// Build ODBC connection string
sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s;DATABASE=MYDBNAME", sDriver, NULL);
TRY{
// Open the database
database.Open(NULL,false,false,sDsn);
SqlString = "INSERT INTO MY_TABLE (id,name,age) VALUES (1,'Sanjaya',25)";
database.ExecuteSQL(SqlString);
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox(L"Database error: " + e->m_strError);
}
END_CATCH;
You should create ODBC Datasource, and it should specify as "ODBC Driver 11 for SQL Server".
I'm using VS Community 2015 and SQL Server 2014.
just add a backslash in your instance name
P2005\SQLEXPRESS2014
P2005\\SQLEXPRESS2014
I've been trying to get a simple program together that can perform some simple operations on a SQL Server database, but can't get any of the tutorials to actually run. I'm trying to figure out if the problem is with the code or with my ODBC settings. Any help/insight is greatly appreciated.
EDIT/UPDATE: ADDITIONAL DETAIL & CODE BELOW
The main program right now is based on this tutorial. I had to make a few changes so that VS Express 2013 would compile the code:
All instances of SQLCHAR * had to be changed to SQLWCHAR *.Had to use wcout to output the error messagesThe 'GOTO: FINISHED' used in the tutorial generated errors that the objects might be uninitialized. I added an 'UNFIN' block after 'FINISHED' and changed those generating errors to GOTO UNFIN to make the compier happyAdded a few debugging markers to make sure I was following the program properlyChanged the connection string to match the server, username and password of the database I'm trying to connect to. Note: Target database uses SQLServer2008
On running the program, I get the following error message (generated by the show_error() function):
Messsage: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
nSQLSTATE: IM002
Could it be something as simple as an ODBC setting that I need to toggle on my machine or a dependency I've missed in the project setup?
Here's the code. (Note that there are extra headers for other features being tested. Said other features are commented out in my current test program and deleted from the below copy-paste to reduce confusion)
#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <sstream>//Used to int to string, and string to int operations
#include <stdlib.h>
#include <fstream>//Used for file opening, appending and writing operations
#include <iostream>
#include <Windows.h>//Used for sleep command, and window "clearwindow" function
#include <sqlext.h> // Used for writing to SQL database
#include <sqltypes.h>
#include <sql.h>
using namespace std;
void show_error(unsigned int handletype, const SQLHANDLE& handle){
SQLWCHAR sqlstate[1024];
SQLWCHAR message[1024];
cout << "In show_error" << endl;
if (SQL_SUCCESS == SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, message, 1024, NULL)){
cout << "Message: ";
wcout << message;
cout << endl << "nSQLSTATE: ";
wcout << sqlstate;
cout << endl;
}
}
bool write_to_database(/*string dbconnection, string fields, string values*/){
SQLHANDLE sqlenvhandle;
SQLHANDLE sqlconnectionhandle;
SQLHANDLE sqlstatementhandle;
SQLRETURN retcode;
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlenvhandle))
goto UNFIN;
if (SQL_SUCCESS != SQLSetEnvAttr(sqlenvhandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
goto UNFIN;
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, sqlenvhandle, &sqlconnectionhandle))
goto UNFIN;
SQLWCHAR retconstring[1024];
cout << "Made it this far at least" << endl;
switch (SQLDriverConnect(sqlconnectionhandle,
NULL,
(SQLWCHAR*)"DRIVER={SQL Server};SERVER=sqlserver.myhost.com, 1433;DATABASE=MyDatabase;UID=xxxxx;PWD=xxxxx",
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:
cout << "Now we're in SQL_ERROR" << endl;
show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
goto FINISHED;
default:
break;
}
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, sqlconnectionhandle, &sqlstatementhandle))
goto FINISHED;
if (SQL_SUCCESS != SQLExecDirect(sqlstatementhandle, (SQLWCHAR*)"select * from testtable", SQL_NTS)){
show_error(SQL_HANDLE_STMT, sqlstatementhandle);
goto FINISHED;
}
else{
char name[64];
char address[64];
int id;
while (SQLFetch(sqlstatementhandle) == SQL_SUCCESS){
SQLGetData(sqlstatementhandle, 1, SQL_C_ULONG, &id, 0, NULL);
SQLGetData(sqlstatementhandle, 2, SQL_C_CHAR, name, 64, NULL);
SQLGetData(sqlstatementhandle, 3, SQL_C_CHAR, address, 64, NULL);
cout << id << " " << name << " " << address << endl;
}
}
FINISHED:
SQLFreeHandle(SQL_HANDLE_STMT, sqlstatementhandle);
SQLDisconnect(sqlconnectionhandle);
SQLFreeHandle(SQL_HANDLE_DBC, sqlconnectionhandle);
SQLFreeHandle(SQL_HANDLE_ENV, sqlenvhandle);
goto ALLOVER;
UNFIN:
cout << "Everything is unfinished" << endl;
ALLOVER:
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
write_to_database();
return 0;
}
EDIT/UPDATE:
Continuing to try and figure out where the error is. Using code based off the tutorial at EasySoft to get the list of DSN available feels a little bit like progress. Here's the updated program and result:
// SQLTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <iostream>
#include <Windows.h>//Used for sleep command, and window "clearwindow" function
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h> // Used for writing to SQL database
using namespace std;
static void extract_error(char *fn, SQLHANDLE handle, SQLSMALLINT handletype){
SQLWCHAR sqlstate[1024];
SQLWCHAR message[1024];
if (SQL_SUCCESS == SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, message, 1024, NULL)){
cout << "Message: ";
wcout << message;
cout << " nSQLSTATE: ";
wcout << sqlstate;
cout << endl;
}
}
static void do_sql(){
SQLHENV env;
SQLWCHAR dsn[256];
SQLWCHAR desc[256];
SQLSMALLINT dsn_ret;
SQLSMALLINT desc_ret;
SQLUSMALLINT direction;
SQLRETURN ret;
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
direction = SQL_FETCH_FIRST;
cout << "SQL DATA SOURCES:" << endl;
while (SQL_SUCCEEDED(ret = SQLDataSources(env, direction,
dsn, sizeof(dsn), &dsn_ret,
desc, sizeof(desc), &desc_ret))) {
direction = SQL_FETCH_NEXT;
wcout << dsn << " | " << desc << endl;
if (ret == SQL_SUCCESS_WITH_INFO) printf("\tdata truncation\n");
}
SQLHDBC dbc;
SQLHSTMT stmt;
SQLWCHAR outstr[1024];
SQLSMALLINT outstrlen;
/* Allocate an environment handle */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* We want ODBC 3 support */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
/* Allocate a connection handle */
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
/* Connect to the DSN mydsn */
string connstr = "DSN=EnglobalConn";
cout << endl << endl << "ATTEMPTING TO CONNECT TO DATA SOURCE USING:" << endl <<connstr << endl << endl;
ret = SQLDriverConnect(dbc, NULL, (SQLWCHAR*)connstr.c_str(), SQL_NTS,
outstr, sizeof(outstr), &outstrlen,
SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(ret)) {
printf("Connected\n");
printf("Returned connection string was:\n\t%s\n", outstr);
if (ret == SQL_SUCCESS_WITH_INFO) {
printf("Driver reported the following diagnostics\n");
extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
}
SQLDisconnect(dbc); /* disconnect from driver */
}
else {
fprintf(stderr, "Failed to connect\n");
extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
}
/* free up allocated handles */
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
}
int _tmain(int argc, _TCHAR* argv[])
{
do_sql();
return 0;
}
The program gives the following output. Error is the same for both 'EnglobalConn' and 'Englobal2'
SQL DATA SOURCES:
dBASE Files | Microsoft Access dBASE Driver (*dbf, *.ndx, *.mdx)
Excel Files | Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)
MS Access Database | Microsoft Access Driver (*.mdb, *.accdb)
Englobal2 | SQL Server
EnglobalConn | SQL Server
ATTEMPTING TO CONNECT TO DATA SOURCE USING:
DSN=EnglobalConn
Failed to connect
Message: [Miscrosoft][ODBC Driver Manager] Data source name not found and no default driver specified nSQLSTATE: IM002
One piece of advice I found while Googling was that a 64-bit Windows install has 2 ODBC sets, one in System32 and one in SysWOW64. I've run both and set the DSNs to be the same:
In C:\Windows\SysWOW64\odbcad32.exe:
User Data Sources: Englobal2 - SQL Server
System DSN: EnglobalConn - SQL Server
In C:\Windows\System32\odbcad32.exe:
User Data Sources: Englobal2 - SQL Server
System DSN: EnglobalConn - SQL Server
Hi I've struggled with exactly the same problem and exactly the same fail :)
(SQLWCHAR*)"DRIVER={SQL Server};SERVER=sqlserver.myhost.com, 1433;DATABASE=MyDatabase;UID=xxxxx;PWD=xxxxx",
Should be
(SQLWCHAR*)_T("DRIVER={SQL Server};SERVER=sqlserver.myhost.com, 1433;DATABASE=MyDatabase;UID=xxxxx;PWD=xxxxx"),
or
(SQLWCHAR*)TEXT("DRIVER={SQL Server};SERVER=sqlserver.myhost.com, 1433;DATABASE=MyDatabase;UID=xxxxx;PWD=xxxxx"),
Hooray! Found a solution that works:
Using the library http://otl.sourceforge.net/ (Designed for use with Oracle, but also works to connect to SQL Server):
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define OTL_ODBC // Compile OTL 4.0/ODBC
// The following #define is required with MyODBC 3.51.11 and higher
#define OTL_ODBC_SELECT_STM_EXECUTE_BEFORE_DESCRIBE
// #define OTL_ODBC_UNIX // uncomment this line if UnixODBC is used
#include "otlv4.h" // include the OTL 4.0 header file
otl_connect db; // connect object
void insert()
// insert rows into table
{
otl_stream o(1, // buffer size should be == 1 always on INSERT
"insert into test_tab values "
"(:f1<int>, : f2<char[31]>), "
"(:f12<int>, : f22<char[31]>), "
"(:f13<int>, : f23<char[31]>), "
"(:f14<int>, : f24<char[31]>), "
"(:f15<int>, : f25<char[31]>) ",
// INSERT statement. Multiple sets of values can be used
// to work around the lack of the bulk interface
db // connect object
);
// If the number of rows to be inserted is not known in advance,
// another stream with the same INSERT can be opened
otl_stream o2(1, // buffer size should be == 1 always on INSERT
"insert into test_tab values "
"(:f1<int>, : f2<char[31]>)",
db // connect object
);
char tmp[32];
int i;
for (i = 1; i <= 100; ++i){
sprintf_s(tmp, "Name%d", i);
o << i << tmp;
}
for (i = 101; i <= 103; ++i){
sprintf_s(tmp, "Name%d", i);
o2 << i << tmp;
}
}
void update(const int af1)
// insert rows into table
{
otl_stream o(1, // buffer size should be == 1 always on UPDATE
"UPDATE test_tab "
" SET f2 = :f2<char[31]> "
" WHERE f1 = : f1<int>",
// UPDATE statement
db // connect object
);
o << "Name changed" << af1;
o << otl_null() << af1 + 1; // set f2 to NULL
}
void select(const int af1)
{
otl_stream i(50, // buffer size may be > 1
"select :f1<int>, :f2<char[31]> from test_tab "
/*"where f1 >= :f11<int> "*/,
// SELECT statement
db // connect object
);
// create select stream
cout << "Here" <<endl;
int f1;
char f2[31];
i << af1 << af1; // :f11 = af1, :f12 = af1
while (!i.eof()){ // while not end-of-data
i >> f1;
cout << "f1 = " << f1 << ", f2 = ";
i >> f2;
if (i.is_null())
cout << "NULL";
else
cout << f2;
cout << endl;
}
}
int main()
{
otl_connect::otl_initialize(); // initialize ODBC environment
try{
//db.rlogon("root / XX #mysql3532");
db.rlogon("driver={SQL Server};UID=XXXXX;PWD=XXXXXX; server=sqlserver.myserver.com"); // connect to ODBC
// db.rlogon("scott/tiger#mysql35"); // connect to ODBC, alternative format
// of connect string
otl_cursor::direct_exec
(
db,
"drop table test_table",
otl_exception::disabled // disable OTL exceptions
); // drop table
otl_cursor::direct_exec
(
db,
"create table test_table(f1 int, f2 varchar(30))"
//"create table test_tab(f1 int, f2 varchar(30)) type=innoDB" (causes MYSQL error)
); // create table
//insert(); // insert records into the table
//update(10); // update records in the table
//select(8); // select records from the table
otl_cursor::direct_exec(db, "INSERT INTO test_table (f1, f2) VALUES (600,'Test')");
otl_cursor::direct_exec(db, "INSERT INTO test_table (f1, f2) VALUES (-3,'Lest')");
otl_cursor::direct_exec(db, "INSERT INTO test_table (f1, f2) VALUES (4,'Rest')");
otl_cursor::direct_exec(db, "INSERT INTO test_table (f1, f2) VALUES (10,'Best')");
otl_cursor::direct_exec(db, "INSERT INTO test_table (f1, f2) VALUES (19,'Quest')");
//select(20);
}
catch (otl_exception& p){ // intercept OTL exceptions
cerr << "MSG: " << p.msg << endl; // print out error message
cerr << "STM_TEXT: " << p.stm_text << endl; // print out SQL that caused the error
cerr << "SQLSTATE: " << p.sqlstate << endl; // print out SQLSTATE message
cerr << "VAR_INFO: " << p.var_info << endl; // print out the variable that caused the error
}
db.logoff(); // disconnect from ODBC
return 0;
}
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.
my C++ program reads a file with sql query and tries to execute it. When I execute the query using phpmyadmin, it works, but when executed in my program, it ends up with the following error:
Code:
ifstream create_file ("create.sql");
if (create_file.is_open())
{
char * create;
int length;
create_file.seekg (0, ios::end);
length = create_file.tellg();
create_file.seekg (0, ios::beg);
create = new char [length];
create_file.read (create,length);
create_file.close();
cout << "Executing query: " << endl;
cout.write (create,length);
cout << "EOF query" << endl;
if(mysql_query(mysql, "CREATE DATABASE grant_db")) {
fprintf(stderr, "Failed to create database: Error: %s\n",
mysql_error(mysql));
}
if(mysql_select_db(mysql, "grant_db")) {
fprintf(stderr, "Failed to select database: Error: %s\n",
mysql_error(mysql));
}
if(mysql_query(mysql, create)) {
fprintf(stderr, "Failed to create table: Error: %s\n",
mysql_error(mysql));
mysql_query(mysql, "DROP DATABASE grant_db");
}
delete[] create;
} else cout << "Unable to open file 'create.sql'.";
Thanks for your help!
You can't put multiple statements in a single mysql_query call. You need to execute them one at a time, by default at least. See the mysql_query docs.
My bet would be that it doesn't handle the /* ... */ comments. Try using -- comments instead.