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'm having trouble connecting to my local SQL Server Express DB. I'm fairly new to c++ and wanted to try messing around with "simple" server connections to mess around with dbs. But I have two main errors I keep getting and haven't figured out I believe everything in the backend is setup correctly (ie. server users/logins & accessibility) heres the code I have atm:
#include "pch.h"
#include <iostream>
#include <windows.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <sql.h>
using namespace std;
void showSQLError(SQLCHAR desc[1024], unsigned int handleType, const SQLHANDLE& handle)
{
SQLCHAR SQLState[1024];
SQLCHAR message[1024];
if (SQL_SUCCESS == SQLGetDiagRec(handleType, handle, 1, SQLState, NULL, message, 1024, NULL))
// Returns the current values of multiple fields of a diagnostic record that contains error, warning, and status information
cout << "At Point:" << desc << endl;
cout << "SQL driver message: " << message << "\nSQL state: " << SQLState << "." << endl;
}
int main()
{
cout << "Hello world" << endl;
SQLHANDLE SQLEnvHandle = NULL;
SQLHANDLE SQLConnectionHandle = NULL;
SQLHANDLE SQLStatementHandle = NULL;
SQLRETURN retCode = 0;
//desc
SQLCHAR noData[1024] = "SQL_NO_DATA\n";
SQLCHAR invalidHandle[1024] = "SQL_INVALID_HANDLE\n";
SQLCHAR error[1024] = "SQL_ERROR\n";
SQLCHAR success[1024] = "Connection succesful";
char SQLQuery[] = "SELECT * FROM roster";
do {
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &SQLEnvHandle))
// Allocates the environment
break;
if (SQL_SUCCESS != SQLSetEnvAttr(SQLEnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
// Sets attributes that govern aspects of environments
break;
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, SQLEnvHandle, &SQLConnectionHandle))
// Allocates the connection
break;
if (SQL_SUCCESS != SQLSetConnectAttr(SQLConnectionHandle, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0))
// Sets attributes that govern aspects of connections
break;
SQLCHAR retConString[1024]; // Conection string
switch (SQLDriverConnect(SQLConnectionHandle, NULL, (SQLCHAR*)"DRIVER={SQL Server Native Client 11.0}; SERVER=MYPC\SQLEXPRESS, 1433; DATABASE=MYdb; UID=myID; PWD=myPWD ", SQL_NTS, retConString, 1024, NULL, SQL_DRIVER_NOPROMPT)) {
// Establishes connections to a driver and a data source
case SQL_SUCCESS:
break;
case SQL_SUCCESS_WITH_INFO:
break;
case SQL_NO_DATA_FOUND:
showSQLError(noData , SQL_HANDLE_DBC, SQLConnectionHandle);
retCode = -1;
break;
case SQL_INVALID_HANDLE:
showSQLError(invalidHandle, SQL_HANDLE_DBC, SQLConnectionHandle);
retCode = -1;
break;
case SQL_ERROR:
showSQLError(error, SQL_HANDLE_DBC, SQLConnectionHandle);
retCode = -1;
break;
default:
break;
}
if (retCode == -1)
break;
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, SQLConnectionHandle, &SQLStatementHandle))
// Allocates the statement
break;
if (SQL_SUCCESS != SQLExecDirect(SQLStatementHandle, (SQLCHAR*)SQLQuery, SQL_NTS)) {
// Executes a preparable statement
showSQLError(success, SQL_HANDLE_STMT, SQLStatementHandle);
break;
}
else {
char name[256];
int age;
while (SQLFetch(SQLStatementHandle) == SQL_SUCCESS) {
// Fetches the next rowset of data from the result
SQLGetData(SQLStatementHandle, 1, SQL_C_DEFAULT, &name, sizeof(name), NULL);
SQLGetData(SQLStatementHandle, 2, SQL_C_DEFAULT, &age, sizeof(age), NULL);
// Retrieves data for a single column in the result set
cout << name << " " << age << endl;
}
}
} while (FALSE);
SQLFreeHandle(SQL_HANDLE_STMT, SQLStatementHandle);
SQLDisconnect(SQLConnectionHandle);
SQLFreeHandle(SQL_HANDLE_DBC, SQLConnectionHandle);
SQLFreeHandle(SQL_HANDLE_ENV, SQLEnvHandle);
// Frees the resources and disconnects
getchar();
}
so my initial error with the above code is:
At Point:SQL_ERROR
SQL driver message: [Microsoft][SQL Server Native Client 11.0]TCP Provider: No such host is known.
SQL state: 08001.
And if I change my connection string to:
SQLDriverConnect(SQLConnectionHandle, NULL, (SQLCHAR*)"DRIVER={SQL Server
Native Client 11.0}; SERVER=MYPC\\SQLEXPRESS, 1433; DATABASE=MYdb;
UID=myID; PWD=myPWD ", SQL_NTS, retConString, 1024, NULL, SQL_DRIVER_NOPROMPT))
NOTE: The added '\' in the SERVER string
I get:
At Point:SQL_ERROR
SQL driver message: [Microsoft][SQL Server Native Client 11.0]TCP Provider: No connection could be made because the target machine actively refused it.
SQL state: 08001.
I beleive the \ is correct but unclear as to why it would be refused. I have setup all the permissions and accounts for the server correctly (assumingly) unless my approach is just straight up incorrect. Where/ would my local server be refusing my connection attempt?
I have never seen an instance name like "MYPC\SQLEXPRESS, 14.0". It should almost certainly be just "MYPC\SQLEXPRESS", and if it actually is "MYPC\SQLEXPRESS, 14.0" it needs to be contained in {} the way the driver name is.
I suggest you use the "sqlcmd -L" command (install it from https://www.microsoft.com/en-us/download/details.aspx?id=53591 if you don't already have it) and use one of the instance names that returns.
The benefit of sqlcmd over other instance listing methods I'm aware of is that sqlcmd uses ODBC and thus you will get a name that the SQL Server ODBC driver is ready to use.
i have a sqlite3 database and i need to query on it using visual c++ 2013?
i am using sqlite3.h for creating connection an manipulate database;
i am using this code to retraive data :
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db, "SELECT * FROM response where list_id =?", -1, &stmt, NULL);
sqlite3_bind_int(stmt, 1, *2*);
tree<SensorState>::iterator itr = sensorTree.begin();
for (;;)
{
int rc = sqlite3_step(stmt);
if (rc == SQLITE_DONE){
break;
}
else if (rc != SQLITE_ROW){
cout << "error in reading sensore with error No: " << rc;
break;
}
const char* name = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
int value = sqlite3_column_int(stmt, 3);
cout << name<< "->" << value <<endl;
}
now in terminal i am getting this outbut:
but it must show this output:
s1->5
s2->2
s4->2
how can i rea string correctly from sqlite3 using c++?
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 want to use SQLite in my c++-Code, so I included SQLite3. When I use the following code in an external *.exe, it works without any problems:
void create_Database(char * file_name)
{
std::ofstream debug("C:\\Users\\Roland-User\\Desktop\\Debug.txt");
//const std::string&filename = file_name;
std::string filename = "C:\\Users\\Roland-User\\Desktop\\data";
std::string appendix = ".database";
std::string file = filename + appendix;
debug << "Creating database\n";
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char * sql;
rc = sqlite3_open(file.c_str(), &db);
if(rc)
exit(-1);
sql = "CREATE TABLE DATABASE(HEADERDATA INT, WAVENUMBER INT, POSX INT, POSY INT, COUNT INT);";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if(rc == 1)
{
sql = "DROP DATABASE DATABASE;";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
sqlite3_free(zErrMsg);
sql = "DROP TABLE DATABASE;";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
sqlite3_free(zErrMsg);
debug << "Having to drop database!\n";
};
sql = "CREATE TABLE DATABASE(HEADERDATA INT, WAVENUMBER INT, POSX INT, POSY INT, COUNT INT);";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if(rc!=SQLITE_OK)
{
debug << "Still there are errors, I am confused!\n";
debug << "With error codes: " << rc << '\n';
sqlite3_free(zErrMsg);
exit(-1);
};
debug << "Finished with creating database\n";
debug.close();
sqlite3_close(db);
};
But when I insert this code in a DLL, I always get an error in my second check (where I get the debug information: "With error codes: "). I always get the error code 1. How can I fix this, and what am I doing wrong?
Thank you very much!