When i figured out how to compile a simple program, now I have other problem ... I installed PostgreSQL and created database and table:
1) createdb testDB 2) create table cities (city varchar(80), location
varchar(80));
And my still very simple program :
#include <iostream>
#include <soci.h>
#include <postgresql/soci-postgresql.h>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
try
{
soci::session sql(soci::postgresql, "dbname=testDB");
string row = "";
sql << "select * from cities;", soci::into(row);
sql << "insert into cities values('London', 'UK')";
sql << "select * from cities;", soci::into(row);
cout << row << "\n";
}
catch (soci::postgresql_soci_error const & e)
{
std::cerr << "PostgreSQL error: " << e.sqlstate() << " " << e.what() << std::endl;
}
catch (std::exception const & e)
{
std::cerr << "Some other error: " << e.what() << std::endl;
}
return 0;
}
This code shows me only rows I already have in my testDB and doesn't show a row that I've just inserted. For example: in my testDB, in table cities, I have:
Warsaw Poland
Berlin Germany
Paris France
and above code shows me:
Warsaw Poland
but doesn't show:
Berlin Germany
Paris France
London UK
Please, help:(
So, adding commit after sql << "insert into cities values ('London', 'UK')";
solve this problem.
Related
I am trying to establish connection with MySQL database in C++ project.And I followed the instructions given in link. After installing Cmake, I was facing problem in Build & Install MySQL Connector/C++.Because CmakeLists.txt does not exists in directory.After some search on web, I have found this answer and followed the steps given, but it didn't work in my case.
Frustrated will all this, I copied all the files(Extracted from dowload link of MySQLConnector C++) into my project folder, and trying to establish connection using this piece of code.
/* Standard C++ includes */
#include <cstdlib>
#include <iostream>
/*
Include directly the different headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include "mysql_connection.h"
#include "mysql_driver.h"
#include "cppconn/driver.h"
#include "cppconn/exception.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
using namespace std;
using namespace sql::mysql;
void db_connection() {
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "root");
/* Connect to the MySQL test database */
con->setSchema("test");
stmt = con->createStatement();
res = stmt->executeQuery("SELECT 'Hello World!' AS _message"); // replace with your statement
while (res->next()) {
cout << "\t... MySQL replies: ";
/* Access column data by alias or column name */
cout << res->getString("_message") << endl;
cout << "\t... MySQL says it again: ";
/* Access column fata by numeric offset, 1 is the first column */
cout << res->getString(1) << endl;
}
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
cout << endl;
}
But it says, undefined reference toget_driver_instance', but it is defined indriver.h`.
Finally, i have found the solution :)
First I completely un-installed MySQL from system (MySQL Client, MYSQL Server and libmysqlcppconn-dev).
After that, install all these again again.
Install MySQL Client and Server.
sudo apt-get install libmysqlcppconn-dev
Now ensure you have all dependencies installed
sudo apt-get build-dep libmysqlcppconn-dev
And now build the package using -lmysqlcppconn.
I am trying to connect to the Microsoft SQL Server database with Poco C++ via ODBC. I have tried to find examples, but havent come across any.
I am simply trying to connect to my database with the following code
#include <iostream>
#include <string>
#include "Poco/Data/Session.h"
using namespace std;
using namespace Poco::Data;
int main()
{
cout << "Testing Poco C++ with MS SQL Server" << endl;
const string CONNECTION_STRING("DRIVER={SQL Server};Server=DESKTOP-32BKOVJ\\SQLEXPRESS;Database=Test2;User ID=sa;Password=IaSS1982;Trusted_Connection=yes;");
Session session("ODBC", CONNECTION_STRING);
return 0;
}
Every time I run this code, I get the following assertion failure:
Assertion violation: _connectors.end() != it [in file "src\SessionFactory.cpp", line 70]
How can I create a simple connection to the MS SQL Database using Poco C++ and ODBC and then print some records on the console?
I was referring to the article Poco ODBC and while SQL loop while trying to write this code.
Any help will be greatly appreciated.
Thank you
I am able to connect to my Microsoft SQL Server 2014 Database using Poco C++ library. Once you have the ODBC drivers installed which are a part of the Windows SDK, the following code should do all basic operations such as
- Create
- Read
- Update
- Delete
#include <iostream>
#include <string>
#include <sstream>
#include "Poco/Data/RecordSet.h"
#include "Poco/Data/Session.h"
#include "Poco/Data/ODBC/Connector.h"
using namespace std;
using namespace Poco::Data;
bool AddUser(Session& session, const size_t& USER_ID, const string& FIRST_NAME, const string& LAST_NAME); // [C]reate
void PrintUsers(Session& session); // [R]etrieve
bool UpdateLastName(Session& session, const string& FIRST_NAME, const string& NEW_LAST_NAME); // [U]pdate
bool DeleteUser(Session& session, const size_t& USER_ID); // [D]elete
int main()
{
try
{
cout << "Testing Poco C++ with MS SQL Server" << endl;
Poco::Data::ODBC::Connector::registerConnector();
const string CONNECTION_STRING("DRIVER={SQL Server};Server=DESKTOP-32BKOVJ\\SQLEXPRESS;Database=Test2;User ID=sa;Password=abc");
//const string CONNECTION_STRING("DSN=PocoMsSQLTest;Uid=sa;Pwd=abc");
Session session("ODBC", CONNECTION_STRING);
if (session.isConnected())
{
PrintUsers(session);
cout << "\n" << endl;
AddUser(session, 5, "Loki", "Moki");
PrintUsers(session);
cout << "\n" << endl;
UpdateLastName(session, "Loki", "Poki");
PrintUsers(session);
cout << "\n" << endl;
DeleteUser(session, 5);
PrintUsers(session);
cout << "\n" << endl;
}
else
{
cerr << "Session not able to connect" << endl;
}
}
catch (const exception& e)
{
cerr << "Exception: " << e.what() << endl;
}
////////////////////////////////////////////////////////
Poco::Data::ODBC::Connector::unregisterConnector();
return 0;
}
// Create
bool AddUser(Session& session, const size_t& USER_ID, const string& FIRST_NAME, const string& LAST_NAME)
{
Statement select(session);
stringstream ss;
ss << "INSERT INTO Users (UserID, FirstName, LastName) VALUES (";
ss << USER_ID << ", " << "\'" << FIRST_NAME << "\'" << ", " << "\'" << LAST_NAME << "\')";
const string& SQL = ss.str();
select << SQL;
return select.execute();
}
// Retrieve
void PrintUsers(Session& session)
{
Statement select(session);
select << "SELECT * FROM Users";
select.execute();
RecordSet rs(select);
bool more = rs.moveFirst();
if (more)
{
cout << rs.columnName(0) << "\t" << rs.columnName(1) << "\t" << rs.columnName(2) << endl;
}
while (more)
{
cout << rs[0].convert<string>() << "\t" << rs[1].convert<string>() << "\t\t" << rs[2].convert<string>() << endl;
more = rs.moveNext();
}
}
// Update
bool UpdateLastName(Session& session, const string& FIRST_NAME, const string& NEW_LAST_NAME)
{
Statement select(session);
stringstream ss;
ss << "UPDATE Users SET LastName=" << "\'" << NEW_LAST_NAME << "\'" << " WHERE FirstName=" << "\'" << FIRST_NAME << "\'";
const string& SQL = ss.str();
select << SQL;
return select.execute();
}
// Delete
bool DeleteUser(Session& session, const size_t& USER_ID)
{
Statement select(session);
stringstream ss;
ss << "DELETE FROM Users WHERE UserID = " << USER_ID;
const string& SQL = ss.str();
select << SQL;
return select.execute();
}
The CONNECTION_STRING that I am using is using the ODBC drivers directly to connect to the database. If you want to use a DSN to connect to the database then comment this CONNECTION_STRING and uncomment the one below.
I did a little bit of research on what is DSN and how to create it in Windows 10. My findings are given below.
What is a DSN?
See https://en.wikipedia.org/wiki/Data_source_name
Creating an ODBC Data Source Name (DSN)
1. Windows 10 search for ODBC
2. Click on Set up ODBC data sources (32-bit)
3. Under the tab "User DSN", click Add
Create New Data Source wizard will start.
4. Select SQL Server and click Finish
5. In the next window
- Give a name. This is the DSN
- Give description
- Click the drop down associated with Server
- Wait for a few seconds
- Databases on your computer or network will show
- Select the database server you want to connect to.
- Click Next
6. In the next window
- Select with SQL Server Authentication
- Enter your Login ID (Username) and Password for that database
- Click Next
7. In the next window
- Select "Change the default database to:" the database you want to connect.
- Click Next
8. In the next window you don't have to change anything just click Finish.
9. A new window appears which has all your DSN information.
10. To test the DSN connection click on "Test Data Source..."
- If everything is ok, a new window appears "TESTS COMPLETED SUCCUSSFULLY!"
- Click OK to exit the result window.
11. Click OK again finish the setup.
12. In the main Window under User Data Sources you will see your newly created DSN.
13. Click OK to exit.
Source: https://www.youtube.com/watch?v=ehVFtmhPwxs
I know there's a lot of suggestions of how to fix this issue, here in this forum, but none of them solved my problem.
It's always the same: code compiles fine and I can use almost all of the getXX members offered by ResultSet, except for getString, that also compiles without problem, but always crash at runtime.
I did some weird tries, like getting a char field using getInt("label") or getBlob("label"), the results weren't good as I previouslly had known, but at least I didn't experience crash.
I tried versions 1.0.5 and 1.1.3+boost. In case of 1.1.3, I also compiled from source, using CMake, but I supose that my knowlegment about the utility is not sufficient and it would last a long time before I have CMake under control. So I'd like to get a more straight solution.
My goal is to create some Win32_Console and WinForms codes, from MSVC 2010, that read and write data in MySQL 5.6 that runs in a XUbuntu machine of my network. And getString() is trapping me a lot.
Thanks in advance
I've added the code bellow:
#include "stdafx.h"
#include <iostream>
#include <mysql_driver.h>
#include <mysql_connection.h>
#include <exception.h>
#include <statement.h>
#include <resultset.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cout<<"Testando uma conexao...\n";
cout<<"Connector 1.1.3:\n";
sql::mysql::MySQL_Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
driver = sql::mysql::get_mysql_driver_instance();
try
{
con = driver->connect("tcp://192.168.1.75:3306", "site_rw", "");
if (con->isClosed()==0)
cout<<"Sucesso!\n\n";
cout<<"Inserindo statement...\n";
stmt = con->createStatement();
stmt->execute("USE test_area");
stmt->execute("DROP TABLE IF EXISTS test");
stmt->execute("CREATE TABLE test(id INT, label CHAR(1))");
cout<<"Criada a tabela...\n";
for (int k=0; k<30;k++)
stmt->execute("INSERT INTO test(id, label) VALUES (1, 'a')");
cout<<"Linhas inseridas...\n";
cout<<"Preparando-se para listar os inteiros:\n";
res = stmt->executeQuery("SELECT * FROM test LIMIT 0,5");
while (res->next())
cout<<"id = " << res->getInt("id") << "\n";
cout<<"\n\nAgora tentando o char(1):\n";
res->beforeFirst();
while (res->next())
cout<<"label = " << res->getString("label");
delete res;
delete stmt;
delete con;
}
catch (sql::SQLException &e)
{
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what() << endl;
cout << " (MySQL error code: " << e.getErrorCode() << endl;
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
cout<<"Terminado...\n";
return 0;
}
Aluísio
São Paulo
Just another problem with Soci... I want to connect with my testDB which I've just created but the code below shows fatal error.
I did this:
On PostgreSQL:
1) CREATE USER robert WITH ENCRYPTED PASSWORD 'pass';
2) CREATE DATABASE testDB;
3) GRANT ALL PRIVILEGES ON DATABASE testDB TO robert;
My C++ code:
#include <iostream>
#include <soci.h>
#include <string>
using std::string;
using std::cout;
#include <postgresql/soci-postgresql.h>
bool connectToDatabase(string databaseName, string user, string password)
{
try
{
soci::session sql(soci::postgresql, "dbname=" +databaseName + " user="+user + " password="+password);
}
catch (soci::postgresql_soci_error const & e)
{
std::cerr << "PostgreSQL error: " << e.sqlstate() << " " << e.what() << std::endl;
return false;
}
catch (std::exception const & e)
{
std::cerr << "Some other error: " << e.what() << std::endl;
return false;
}
return true;
}
int main(int argc, char **argv)
{
cout << connectToDatabase("testDB", "robert", "pass");
return 0;
}
after compilation I got this:
Some other error: Cannot establish connection to the database.
FATAL: database "testDB" does not exist
What's wrong?
Connect to database "testdb" instead.
Case folding in PostgreSQL works by converting unquoted identifiers to lower case. So CREATE DATABASE testDB creates a database called "testdb", in contrast to CREATE DATABASE "testDB".
(As a general piece of advice: either get used to using all-lowercase identifiers, maybe with underscores between words, or get used to quoting identifiers all the time. The former is more natural for PostgreSQL, the latter allows you to stick with your convention despite it).
What solutions are there for making a simple connection to a MySQL database in C++?
I find MySQL Connector from dev.mysql.com hard to integrate.
Anticipated thanks!
Its pretty simple to communicate with MySQL from C/C++ application
you need to include mysql.h header file
three basic APIs to connect and execute query
mysql_connect()
mysql_query()
mysql_close()
Link with mysql library (libMysql)
You could try the ODBC path, with a support library.
Some year ago I used OTL to interface SqlServer and found it efficient. Now I've tried to interface MySql, without any problem so far:
#include <otlv4.h>
#include <iostream>
using namespace std;
int otl_x_sql_main(int argc, char **argv)
{
otl_connect db; // connect object
otl_connect::otl_initialize(); // initialize ODBC environment
try {
db.rlogon("DRIVER=mysql;DB=...;UID=...;PWD=..."); // connect to ODBC
// parametrized SELECT
otl_stream i(50, "SELECT product_id,model FROM product WHERE product_id >= :f<int> AND product_id < :ff<int>", db);
int product_id;
char model[100];
i << 1000 << 2000; // assigning product_id range
// SELECT automatically executes when all input variables are assigned
while (!i.eof()) {
i >> product_id >> model;
cout << "product_id=" << product_id << ", model=" << model << endl;
}
}
catch(otl_exception& p) { // intercept OTL exceptions
cerr << p.msg << endl; // print out error message
cerr << p.stm_text << endl; // print out SQL that caused the error
cerr << p.sqlstate << endl; // print out SQLSTATE message
cerr << p.var_info << endl; // print out the variable that caused the error
}
return 0;
}