I wrote an example application in C++(on Eclipse Luna) using sqlapi++ libraries to connect to an Oracle database I created with sqldeveloper.
The program compiles without errors, but when I run it,nothing appears on the console.
(I am using Windows 7)
Here the Database information:
Database name:"DB Casa Editrice"
Host:localhost
SID:xe
Port:1521
And the code:
#include <iostream>
#include "SQLAPI.h"
using namespace std;
int main() {
SAConnection con; // create connection object
try {
con.Connect( "DB Casa Editrice", // database name
"system", // user name
"shruikan94", // password
SA_Oracle_Client );
cout << "We are connected!\n";
con.Disconnect();
cout << "Disconnected!\n";
}
catch( SAException &x )
{
// SAConnection::Rollback()
// can also throw an exception
// (if a network error for example),
// we will be ready
try {
// on error rollback changes
con.Rollback();
}
catch( SAException & )
{
}
// print error message
cout << "ERROR\n";
}
return 0;
}
Related
I can't access database from C++
every time it just throws error: FATAL: Ident authentication failed for user "testuser"
I had tried:
Reinstalling postgresql11 to postgresql12
Creating user
Creating database with owner testuser
Changing pg_hba.conf localhost from peer to md5
Changing the password of user multiple times
Rebooting computer
Restarting Service
here is the code:
#include "gtest/gtest.h"
#include <iostream>
#include <pqxx/pqxx>
using std::cin;
using std::cout;
using std::cerr;
using namespace std;
using namespace pqxx;
int main() {
try {
connection C("dbname = relay user = testuser password = 1234 hostaddr = 127.0.0.1 port = 5432");
if (C.is_open())
cout << "Opened database successfully: " << C.dbname() << endl;
else {
cout << "Can't open database" << endl;
return 1;
}
C.close();
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return 1;
}
}
TEST(postgreDB_test_trivial, trivial_test) {
main();
}
I allowed even firewall access for ports
I don't have any more ideas on how to resolve this.
The problem was that uninstalling Postgres11 and installing Postgres12 left pg_hba.conf with different setting after I restarted service so I needed to change everything to trust in pg_hba.conf to get it to work
I am currently debugging a containerized C++ application, it seems like it's throwing exception and complaining about the database connection, error:
terminate called after throwing an instance of 'otl_tmpl_exception<odbc::otl_exc, odbc::otl_conn, odbc::otl_cur>'
Aborted
The code in main() is below:
int main(int ac, char *av[])
{
auto otl_connect = std::make_unique<odbc::otl_connect>("Driver={/usr/local/lib/libmyodbc8a.so};server=xxx.x.x.x;port=xxxx;database=xxxx;user=xxx;password=xxx");
std::stringstream query;
query << "SELECT x FROM xxx.xxxs;";
odbc::otl_stream the_stream(1000, query.str().c_str(), *otl_connect);
std::string
int val;
while(!the_stream.eof())
{
the_stream >> xxx >> val;
std::cout << xxx << " " << val << "\n";
}
the_stream.close();
}
I'm totally new to C++, can someone explain what the codes in main() is doing and how to fix the exception error message, I've been working on this for a whole afternoon, exhausted....help!!!!
I'm not very familiar with the Oracle, ODBC and DB2-CLI Template Library but I had a go using it with a MySql database on my Ubuntu Linux.
This is how I was able to run a simple query. I think the code below is fairly self-explanatory.
As you'll see, it's quite different from your code. The driver is mysql. You have to substitute ... with the real database name, user name and password of your database. You also have to initialise the ODBC environment first and connect to your database using rlogon().
#include <iostream>
#define OTL_ODBC // Compile OTL 4.0/ODBC
#define OTL_ODBC_UNIX
#include "otlv4.h"
int main()
{
otl_connect db; // connect object
otl_connect::otl_initialize(); // initialize ODBC environment
try {
db.rlogon("DRIVER=mysql;DB=...;UID=...;PWD=..."); // connect to ODBC
otl_stream os(50, "SELECT id FROM task", db);
int id;
// SELECT automatically executes when all input variables are assigned
while (!os.eof())
{
os >> id;
std::cout << "id=" << id << std::endl;
}
}
catch(otl_exception& p) { // intercept OTL exceptions
std::cerr << p.msg << std::endl; // print out error message
std::cerr << p.stm_text << std::endl; // print out SQL that caused the error
std::cerr << p.sqlstate << std::endl; // print out SQLSTATE message
std::cerr << p.var_info << std::endl; // print out the variable that caused the error
}
return 0;
}
Make sure that you have a variable for each field you want to read from the query result. It seems that you can't extract values into std::string variables; you have to use char arrays (e.g. char name[20]) instead.
Hope this helps.
In php I create a config file that opens a connection to the database and then I use that file in all my other files in order to open a connection also. But I can't seem to find a way to do the same thing with c++. I can connect to the database but I can't use it as a class because I have a main() inside it and I can't seem to make it work without the main. This is my code:
// Standard C++ includes
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
// Include the Connector/C++ headers
#include "cppconn/driver.h"
#include "cppconn/exception.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
// Link to the Connector/C++ library
#pragma comment(lib, "mysqlcppconn.lib")
// Specify our connection target and credentials
const string server = "localhost";
const string username = "root";
const string password = "";
int main()
{
sql::Driver *driver; // Create a pointer to a MySQL driver object
sql::Connection *dbConn; // Create a pointer to a database connection object
sql::Statement *stmt; // Create a pointer to a Statement object to hold our SQL commands
sql::ResultSet *res; // Create a pointer to a ResultSet object to hold the results of any queries we run
// Try to get a driver to use to connect to our DBMS
try
{
driver = get_driver_instance();
}
catch (sql::SQLException e)
{
cout << "Could not get a database driver. Error message: " << e.what() << endl;
system("pause");
exit(1);
}
// Try to connect to the DBMS server
try
{
dbConn = driver->connect(server, username, password);
}
catch (sql::SQLException e)
{
cout << "Could not connect to database. Error message: " << e.what() << endl;
system("pause");
exit(1);
}
stmt = dbConn->createStatement();
// Try to query the database
try
{
stmt->execute("USE test");
res = stmt->executeQuery("SELECT * FROM users");
}
catch (sql::SQLException e)
{
cout << "SQL error. Error message: " << e.what() << endl;
system("pause");
exit(1);
}
sql::ResultSetMetaData *res_meta = res -> getMetaData();
int columns = res_meta -> getColumnCount();
while (res->next())
{
for (int i = 1; i <= columns; i++) {
cout << res->getString(i) << " | " ;
}
cout << endl;
}
delete res;
delete stmt;
delete dbConn;
return 0;
}
You need to create a class (e.g class DBConnector)and declare functions in header file.
For example this piece of code can go into one function:
sql::Driver* DBConnector::GetDriverInstance()
{
try
{
m_driver = get_driver_instance();
}
catch (sql::SQLException e)
{
cout << "Could not get a database driver. Error message: " << e.what() << endl;
system("pause");
exit(1);
}
return m_driver;
}
Here sql::Driver *m_driver is expected to be declared as a member variable of class in header file. You might need to read more about classes and member functions and variables before actually going ahead with code.
Other than this, you need to take very good care of memory management. I would suggest you read more and use smart pointers like std::shared_ptr.
I've been programming in C++ with VS 2010 Professional but I am stuck on this problem:
If the program starts and the connection is good then it loads the "gameactive" loop, and displays the high score of the player.
But when the connection has a error it freezes and crashes. I want to display a error like "error connecting to server" and continue loading the game.
I did use this tutorial:
http://r3dux.org/2010/11/how-to-use-mysql-connectorc-to-connect-to-a-mysql-database-in-windows/
Here is my code:
// Standad C++ includes
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
#include <string.h>
// Include the Connector/C++ headers
#include "cppconn/driver.h"
#include "cppconn/exception.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
#include <cgl\cgl.h>
#include <cgl\core.h>
#include <core\corefile.h>
// Link to the Connector/C++ library
#pragma comment(lib, "mysqlcppconn.lib")
// Specify our connection target and credentials
const string server = "tcp://xxx.xxx.xxx.xxx:3306";
const string username = "xxxxxxx";
const string password = "XXxxXXxxXXxx";
char myoutput[1024];
char myoutput1[1024];
char myoutput2[1024];
s_font font;
s_bitmap bmp_background;
int connectsetup()
{
sql::Driver *driver; // Create a pointer to a MySQL driver object
sql::Connection *dbConn; // Create a pointer to a database connection object
sql::Statement *stmt; // Create a pointer to a Statement object to hold our SQL commands
sql::ResultSet *res; // Create a pointer to a ResultSet object to hold the results of any queries we run
// Try to get a driver to use to connect to our DBMS
try
{
driver = get_driver_instance();
}
catch (sql::SQLException e)
{
cout << "Could not get a database driver. Error message: " << e.what() << endl;
}
// Try to connect to the DBMS server
try
{
dbConn = driver->connect(server, username, password);
}
catch (sql::SQLException e)
{
cout << "Could not connect to database. Error message: " << e.what() << endl;
}
stmt = dbConn->createStatement(); // Specify which connection our SQL statement should be executed on
// Try to query the database
try
{
stmt->execute("USE runner"); // Select which database to use. Notice that we use "execute" to perform a command.
res = stmt->executeQuery("SELECT * FROM highscores"); // Perform a query and get the results. Notice that we use "executeQuery" to get results back
}
catch (sql::SQLException e)
{
cout << "SQL error. Error message: " << e.what() << endl;
}
// While there are still results (i.e. rows/records) in our result set...
while (res->next())
{
// ...get each field we want and output it to the screen
// Note: The first field/column in our result-set is field 1 (one) and -NOT- field 0 (zero)
// Also, if we know the name of the field then we can also get it directly by name by using:
// res->getString("TheNameOfTheField");
//printf(myoutput,"%s %s %s",res->getString(1),res->getString(2),res->getString(3));
strcpy(myoutput,res->getString(1).c_str());
strcpy(myoutput1,res->getString(2).c_str());
strcpy(myoutput2,res->getString(3).c_str());
}
// Clean up after ourselves
delete res;
delete stmt;
delete dbConn;
return 0;
}
void coremain()
{
//Fullscreen, windowed of scaled?
corefile_mountimage("res",MOUNT_DIR);
CGL_InitVideo(1280, 720, CGL_VIDEO_NONE);
CGL_SetTitle("CGL - Endless poepert");
CGL_InitFont("font_heat.tga", &font);
CGL_LoadBitmap("track1.tga",&bmp_background);
connectsetup();
int gameactive=1;
int getal=atoi(myoutput);
do {
do {
CGL_WaitRefresh();
CGL_DrawBitmap(0,0,bmp_background);
CGL_DrawCenteredText(100,font, "%s: %d van %s score %s",myoutput,getal,myoutput1,myoutput2);
int key,keytrig;
CGL_GetKeys(&key,&keytrig);
if (keytrig & CGL_INPUT_KEY_EXIT) exit(EXIT_SUCCESS);
CGL_SwapBuffers();
} while(gameactive);
CGL_FlushGraphics();
} while(1);
CGL_CloseVideo();
}
The issue seems to be your connectSetup function. You have try/catch blocks, but you don't do anything if there is an issue. You just keep going as if nothing is wrong.
Also, this is a great time to learn smart pointers. The reason why smart pointers should be used here is in the case where something goes wrong even if the database connection is successful (you have subsequent try/catch blocks). You want to ensure that anything that was allocated is cleaned up, regardless of when or where you issue a return statement.
#include <memory>
#include <string>
std::string myoutput;
std::string myoutput1;
std::string myoutput2;
int connectsetup()
{
sql::Driver* driver;
std::unique_ptr<sql::Connection> dbConn;
std::unique_ptr<sql::Statement> stmt;
std::unique_ptr<sql::ResultSet> res;
try
{
driver = get_driver_instance();
dbConn.reset(driver->connect(server, username, password))
stmt.reset(dbConn->createStatement());
stmt->execute("USE runner");
res.reset(stmt->executeQuery("SELECT * FROM highscores")); // Perform a query
while (res->next())
{
myoutput = res->getString(1);
myoutput1 = res->getString(2);
myoutput2 = res->getString(3);
}
}
catch (const sql::SQLException& e)
{
cout << "Something went wrong with the database stuff. Here it is: " << e.what() << endl;
return -1;
}
return 0;
}
This code was not compiled, but I attempted to extract what your original code was doing and rewrote it using smart pointers.
The code above will throw an exception if any of those statements fail. Note that we catch the exception by reference, not by value. Also note that there is no need for delete, since std::unique_ptr does this work automatically.
Finally, there is no need for char arrays -- why did you introduce them? It only made another part of your function vulnerable to a memory overwrite, namely in the res->next() loop.
Another question on a Mysql connection failing:
I'm using the Poco library (1.5.2) and I would like to know why, when I try to open a MySQL connection, I got this message:
Connection attempt failed
Whereas, when I try a connection via console (mysql -u root -p ...), it works.
Maybe I forget an important step in the MySQL configuration ?
Here is my code :
#include <iostream>
#include <string>
#include <Poco/Data/MySQL/MySQLException.h>
#include <Poco/Data/MySQL/Connector.h>
#include <Poco/Data/SessionFactory.h>
using namespace std;
int main()
{
Poco::Data::MySQL::Connector::registerConnector();
try
{
string str = "host=localhost;user=root;password=mypassword;compress=true;auto-reconnect=true";
Poco::Data::Session test(Poco::Data::SessionFactory::instance().create(Poco::Data::MySQL::Connector::KEY, str ));
}
catch (Poco::Data::MySQL::ConnectionException& e)
{
cout << e.what() << endl;
return -1;
}
catch(Poco::Data::MySQL::StatementException& e)
{
cout << e.what() << endl;
return -1;
}
return 0;
}
Thank you !!
ok the problem was the "localhost" value for "host" doesn't work on my linux (I don't know why). For fixing the bug, I had to change my string to:
string str = "host=127.0.0.1;user=root;password=mypassword;compress=true;auto-reconnect=true";