Selecting multiple tables MySQL - c++

I'm using MySQL connector C 6.0.2, I need to select Table1 and read some values there then switch to table2 and read the values there too etc, I have more than two tables I need to switch from table to table. How can I do this ?
example code:
connect=mysql_real_connect(connect,SERVER,USER,PASSWORD,DATABASE,0,NULL,0);
if(connect)
{
MYSQL_RES *res_set;
MYSQL_ROW row;
////table1
mysql_query(connect,"SELECT * FROM `Table1` WHERE `Column2`='1234'");
unsigned int i = 0;
res_set = mysql_store_result(connect);
unsigned int numrows = mysql_num_rows(res_set);
if(numrows==0)
{
return false;
}else
{
while ((row = mysql_fetch_row(res_set)) != NULL)
{
if(strcmp(row[2], "true")==NULL)
{/////////Here I need to read or get the values from Table2
///Select table two
}else
return false;
}
}
}
Update: I think I have solved it, it was pretty simple
connect=mysql_real_connect(connect,SERVER,USER,PASSWORD,DATABASE,0,NULL,0);
if(connect)
{
MYSQL_RES *res_set;
MYSQL_ROW row;
////table1
mysql_query(connect,"SELECT * FROM `Table1` WHERE `Column2`='1234'");
res_set = mysql_store_result(connect);
unsigned int numrows = mysql_num_rows(res_set);
if(numrows==0)
{
return false;
}else
{
while ((row = mysql_fetch_row(res_set)) != NULL)
{
if(strcmp(row[2], "true")==NULL)
{/////////Here I need to read or get the values from Table2
///Select table two
MYSQL_RES *res_set2;
////table2
mysql_query(connect,"SELECT * FROM `Table2` WHERE `Column2`='1234'");
res_set2 = mysql_store_result(connect);
unsigned int numrows2 = mysql_num_rows(res_set2);
if(numrows2==0)
{
//no result
}else
{
//do something
}
}else
return false;
}
}
}

You have the res_set variable that you got from your query; you'd get another variable from your second query. You don't switch between tables, you just get the right values from the right query results.
Also note that this sounds a lot like you should be doing this inside your SQL query, and not inside your code, but that entirely depends on what you want to do.

I suggest you play with your SQL statement to return the result sets from both tables.
Research the "SELECT JOIN" statement.
The rule of thumb is to have the data perform most of the database work, including searching multiple tables.

Related

Need code for wxListCtrl change to working code for virtual style wxListCtrl

I am new in c++ and I use for GUI wxWidget. My question is how this code for wxListCtrl change to working code for virtual ListCtrl...
now my code is below and work but I have to try with virtual style
wxString SQL = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + table + "'";
int gstate = mysql_query(conn,SQL);
if(!gstate){
res = mysql_store_result(conn);
int num = 0;
lcData->SetColumnWidth(0,wxLIST_AUTOSIZE_USEHEADER);
lcData->InsertColumn(0,"rb.");
while(row = mysql_fetch_row(res)){
lcData->SetColumnWidth(num+1, wxLIST_AUTOSIZE_USEHEADER);
lcData->InsertColumn(num+1,row[0]);
num++;
}
if(res != NULL)
mysql_free_result(res);
}
SQL = tcSQL->GetValue();
tcLog->AppendText(SQL+"\n");
gstate = mysql_query(conn,SQL);
if(!gstate){
res = mysql_store_result(conn);
long num_field = mysql_num_fields(res);
long num = 0;
lcData->SetColumnWidth(0,40);
while(row = mysql_fetch_row(res)){
lcData->InsertItem(num, wxString::Format(_T("%4d"),num+1));
for(long i = 0; i < num_field; i++){
lcData->SetItem(num,i+1,row[i] );
}
num++;
}
if(res != NULL)
mysql_free_result(res);
Where I compiling the program and run I have this error :
SharedScreens
Thx.
YuMERA
The idea of a virtual wxListCtrl is that you don't put the data into it, but provide the data on request, when the control needs it. So to use the virtual control, you need to change the structure of your code and avoid getting all the items from the database in the first place and, instead, retrieve them on demand from your overridden OnGetItemText() method. Of course, in order to be able to override it, you must derive your own class from wxListCtrl first and you also need to tell the control how many items is it going to have (which you would obtain from select count(*) ... query in your case).

Is the return of last_insert_id always correct?

If I have the 2 following functions:
int AccessDb::InsertColValue(string tableName, string col, string val)
{
try
{
sql::Statement *stmt;
bool ret;
if ((nomTable != "") && (col != "") && (val != ""))
{
string query = "INSERT INTO " + tableName + "(" + col + ") values (";
query += val + ");";
stmt = con->createStatement();
ret = stmt->execute(query);
}
delete stmt;
return 0;
}
catch (sql::SQLException &e)
{
return -1;
}
}
and
long AccessDb::LastInsertId()
{
try
{
sql::Statement *stmt;
sql::ResultSet *res;
string query = "SELECT LAST_INSERT_ID() AS LAST_ID";
stmt = con->createStatement();
res = stmt->executeQuery(query);
delete stmt;
long lastId;
while (res->next())
{
lastId = res->getInt("LAST_ID");
}
return lastId;
}
catch (sql::SQLException &e)
{
return -1;
}
}
Can I be sure that the return of LastInsertId() will always give me the correct id if I write the following lines and if the id is auto generated by the database?
AccessDb adb; // initialize the connexion with the db
int ret = adb.InsertColValue("people", "name", "John");
if (ret == 0)
long lastId = adb.LastInsertId();
If the previous code is called somewhere else at the same time, can I have a wrong value in my lastId variable ? If yes, do I have to use locks and unlocks on my table to avoid that or another solution ?
Here's what the docs says:
The ID that was generated is maintained in the server on a
per-connection basis. This means that the value returned by the
function to a given client is the first AUTO_INCREMENT value generated
for most recent statement affecting an AUTO_INCREMENT column by that
client. This value cannot be affected by other clients, even if they
generate AUTO_INCREMENT values of their own. This behavior ensures
that each client can retrieve its own ID without concern for the
activity of other clients, and without the need for locks or
transactions.
So, unless your own code on the client is sharing a connection between several threads (Which it looks like you're not, since there are no mutexes or locks in your code) you can be sure SELECT LAST_INSERT_ID() isn't mixed up with any other connection or client.
I can't find the docs for the C++ mysql library but verify what the return value of ret = stmt->execute(query); in your InsertColValue() function means, such that you're sure the only possible way that you fail to insert anything is when an exception is thrown.

Columns number. QMYSQLResult::data: column out of range

Have database. Have query with unknown count of columns. Need to put all answer in QList
database = QSqlDatabase::addDatabase("QMYSQL");
...
QString sql = "Select * from test";
QSqlQuery query = QSqlQuery(database);
query.exec(sql);
QList<QStringList> retList;
Use .isValid() on value.
while (query.next()) {
int count = 0;
bool flagValues = true;
QStringList row;
while(flagValues)
{
QVariant value = query.value(count);
if(value.isValid() && !(count == memCount) )
{
count++;
row.append(value.toString());
}
else
{
flagValues = false;
}
}
retList.append(row);
All is ok, but i have a messages (not error) like in every row. :
QMYSQLResult::data: column 3 out of range
I do not want to use additional query (like information_schema) to know columns number.
Use query.record().count() to obtain the number of columns. Thus:
database = QSqlDatabase::addDatabase("QMYSQL");
...
QString sql = "Select * from test";
QSqlQuery query = QSqlQuery(database);
query.exec(sql);
const int memCount = query.record().count();
// query loop goes here

How to count the numbers of columns while iterating over results using Oracle OCCI library?

Help me, I want to make a generic function that get the results of any query string and puts all rows into another variable. When iterating over a row, how can I know the numbers of columns available?
Environment *env = Environment::createEnvironment();
Connection *conn = env->createConnection("user","pass");
quantLinhas = 0;
if( conn != NULL ) {
Statement *stmt = conn->createStatement(query);
ResultSet *rs = stmt->executeQuery();
resultadoSQL->linhas.clear();
while (rs->next()) {
aux.campos.clear();
numbers_colums = rs->whatever_method() //WHAT DO I DO HERE??
for(i = 0; i < numbers_colums ; i++) {
aux.campos.push_back( rs->getString(i) );
quantLinhas++;
}
resultadoSQL->linhas.push_back( aux );
}
stmt->closeResultSet(rs);
conn->terminateStatement(stmt);
env->terminateConnection(conn);
}
According the documentation you can use getColumnListMetaData function. The number of elements in the returned vector might be what you want. You may check if each element is of PTYPE_COL to ensure it.
try this
vector<MetaData> columnList = rs->getColumnListMetaData();
numbers_colums = columnList.size();
columnList.clear();
it worked for me.
source link

How to use the MySQL count() function in QT?

I want to get the total number of rows in a table. How can I achieve this?
I wrote the code as follows:
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("Dictionary");
db.setUserName("root");
db.setPassword("cinesoft");
bool ok = db.open();
int ID;
//SELECT COUNT(*) FROM icecream
QString IDnosql="SELECT * FROM Dictionary.TABLE_ENGLISH";
if(ok)
{
QSqlQuery IDquery(db);
IDquery.prepare(IDnosql);
int Id=IDquery.numRowsAffected();
IDquery.exec();
// int Id=IDquery.numRowsAffected();
QMessageBox::information(0,"sucess",QString::number(Id));
}
I use the count command. I want to get the total no of rows in my table and store to an integer variable.
You can prepare a QSqlQuery with the COUNT command:
QSqlQuery q;
q.prepare(QString("SELECT COUNT (*) FROM %1").arg(tableName));
q.exec();
int rows= 0;
if (q.next()) {
rows= q.value(0).toInt();
}
Check QSqlQuery for more details
Why don't you just use the query SELECT COUNT(*) from Dictionary.TABLE_ENGLISH - this will give you the number of rows in the table. Then get this value from the result set and store it in an integer variable.
When using a COUNT statement, you can use QSqlQuery::value( int index ) like when selecting a single value:
QString IDnosql="SELECT COUNT( * ) FROM Dictionary.TABLE_ENGLISH";
if(ok)
{
QSqlQuery IDquery(db);
IDquery.prepare(IDnosql);
if( !IDquery.exec() )
{
// TODO: perform error handling here!
}
if( !IDquery.next() )
{
// TODO: Error handling: Query did not return a result (no row, which should not be possible when using a count statement as you would always get 1 row)
}
int Id = IDquery.value( 0 ).toInt();
QMessageBox::information(0,"sucess",QString::number(Id));
}
To get the total number of rows in a table A you simply
SELECT count(*) from A;
Then you need to convert the result to an integer.