C++ MySql get last inserted id - c++

I´m having the following code that insert a row into mysql database and return the inserted id:
/*
* Execute the statement
*/
std::string sql = "INSERT INTO TABLE (A, B, C) VALUES (1, 2, 3)";
sql::Statement *stmt;
stmt = connection->createStatement();
stmt->execute(sql);
/*
* Get the returned id
*/
stmt = connection->createStatement();
sql::ResultSet *res = stmt->executeQuery("SELECT ##identity AS id");
res->next();
model.modelId = res->getInt64("id");
My questions are:
Do I really need to call connection->createStatement() again ?
I think this may overload the code, as I need to call twice the database.
Is there a way to optimize this code ?
Is there other way to get the last inserted id ?
Thanks for helping.

Just for the reference, ##identity is MSSQL-specific system function, that also returns last-insert id but for MSSQL, not for MySQL.
To get last-insert id in MySQL, since you have asked specifically for MySQL, you need to change your SELECT statement to following:
SELECT LAST_INSERT_ID() AS id;
Also, since stmt->execute() and stmt->executeQuery() methods take String, as input argument, I am sure that you don't need to connection->createStatement() again. Just to confirm, I just googled it and found this link.
Please note that this answer is specifically for MySQL, as this question is about MySQL. Hope it helps.

Related

Retrieve Data from Database by Passing an ID, c++

I am trying to fetch data from my database giving it only an ID number. My database has 2 columns, first is ID, and second is an image path.
so if i pass ID=3, it should return the path corresponding to that ID.
I have tried to do that, but I am stuck at query.
mysql_query (conn, "SELECT * FROM table" );
res = mysql_use_result(conn);
row = mysql_fetch_row(res)
ID = atoi(row[0]);
path = row[1];
printf("ID: %i", ID);
printf("Image Path: %s", path);
Please help:)
I think the question is not really clear. First case, for each row you want to display id/path:
mysql_query (conn, "SELECT * FROM table" );
res = mysql_use_result(conn);
while (row = mysql_fetch_row(res)) {
ID = atoi(row[0]);
path = row[1];
printf("ID: %i", ID);
printf("Image Path: %s", path);
}
Other possibility, you want only one row because you know the ID you are looking for. Then you can decide to retrieve only the missing column with something like:
mysql_query (conn, "SELECT path FROM table WHERE id=ID" );
In some more complicated cases, lets say even if with the WHERE you may have multiple rows, you can keep only the first one for example by adding the TOP condition in your query. In any cases you need to think on what will be returned for real.
I didn't test the code I wrote, just edited a bit what you posted (just to be fair ^^)
You seem to have a few problems with basic computer concepts. For instance, the concept of having one thing versus more things. You fetch one row, but your database table has multiple rows and your query returns all rows. (No WHERE clause).
The obvious solution is to either fetch all rows, or (better) restrict your query to just the row you want.

How to prepare a C++ string for sql query

I have to prepare strings to be suitable for queries because these strings will be used in the queries as field values. if they contain a ' etc the sql query fails to execute.
I therefore want to replace ' with '' I have seen the code to find and replace a substring with a substring. but I guess the problem is a little tricky because replacing string also contains two single quotes '' replacing one quote ' so when I have to find the next occurance it would encounter a ' which was intentionally replaced.
I am using Sql lite C api and the example query might look like this
select * from persons where name = 'John' D'oe'
Since John Doe contain a ' the query will fail , so I want all occurances of ' in the name to replaced with ''
Any ideas how you guys prepares your field values in query to be used in sql ??? may be it's a basic thing but I am not too smart in C/C++.
your help would be very helpful
Use queries with arguments instead of replacing stuff, which could lead to several problems (like SQL injection vulnerabilities).
MySQL example:
sql::Connection *con = ...;
string query = "SELECT * FROM TABLE WHERE ID = ?";
sql::PreparedStatement *prep_stmt = con->prepareStatement(query);
prep_stmt->setInt(1, 1); // Replace first argument with 1
prep_stmt->execute();
This will execute SELECT * FROM TABLE WHERE ID = 1.
EDIT: more info for SQLite prepared statements here and here.
It depends on the SQL Library you are using. Some of them will have the concept of a PreparedStatement, which you will use question marks in place of the variables, then when you set those variables on the statement, it will internally ensure that you cannot inject sql commands.

Empty blob insert query in ODBC c ++ (oracle)

I need to insert a blob in o oracle database. I am using c++ and ODBC library.
I am stucked at the insert query and update query .It is abstract for me how to make an blob insert query.
I know how to make an query for a non blob column.
My table structure is :
REATE TABLE t_testblob (
filename VARCHAR2(30) DEFAULT NULL NULL,
apkdata BLOB NULL
)
I found an exemple on insert and update :
INSERT INTO table_name VALUES (memberlist,?,memberlist)
UPDATE table_name SET ImageFieldName = ? WHERE ID=yourId
But these structure of querys or abstract to me . What should memberlist be ? why is there "?" where are the values to be inserted ?
Those question marks means that it is PreparedStatement. Such statements are good for both server and client. Server has less work because it is easier to parse such statement, and client do not need to worry about SQLInjection. Client prepares such query, builds buffer for input values and calls it.
Also such statement is executed very quick compared to "normal" queries, especially in loops, importing data from csv file etc.
I don't know what ODBC C++ library you use while ODBC is strictly C library. Other languages like Java or Python can use it too. I think the easiest is example in Python:
cursor = connection.cursor()
for txt in ('a', 'b', 'c'):
cursor.execute('SELECT * FROM test WHERE txt=?', (txt,))
Of course such PreparedStatement can be used in INSERT or UPDATE statements too, and for your example it can look like:
cursor.execute("INSERT INTO t_testblob (filename, apkdata) VALUE (?, ?)", filename, my_binary_data)

SQLite - How to use it at terminal level & C++ application?

i am new to sqlite and I just recently installed it. I am familar with mysql but I need to use sqlite as I am using it for a C++ application that I am going to create.
Question 1:
I type this at my command line terminal
root#ubuntu:/home/baoky/version1.2/Assignment 2# sqlite abeserver.db
then I saw this output
sqlite>
So i type .h and i see a list of help commands
But i wanna create a table
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /home/baoky/version1.2/Assignment 2/abeserver.db
1 temp /var/tmp/sqlite_hjT3FEefcAHRPhn
in my main database
How do i execute this sql command at terminal level
CREATE TABLE abe_account (
username TEXT,
name TEXT,
department TEXT,
password TEXT
);
Question 2:
How do I insert record into the table abe_account using C++
Question 3:
How do I retrieve records from table abe_account and assign it to a string using C++
Sorry I tried google around and search around stack overflow, I am still confused with the usage, if its mysql, it would be much simple for me.
Question 2:
Question 3:
Let me google it for you, friend: An Introduction To The SQLite C/C++ Interface.
If you are using the sqlite terminal, you can just type SQL there, and it will be executed.
A typical cycle of work from your C++ code will look something like this:
sqlite3 * db;//database
sqlite3_stmt * stmt;//sql statement
sqlite3_open( "database.db", & db );//opening database
sqlite3_prepare( db, "SELECT something FROM something else;", -1, &stmt, NULL );//preparing the statement
sqlite3_step( stmt );//executing the statement
while( sqlite3_column_text( stmt, 0 ) )
{
char * str = (char *) sqlite3_column_text( stmt, 0 );///reading the 1st column of the result
//do your stuff
sqlite3_step( stmt );//moving to the next row of the result
}
sqlite3_finalize(stmt);
sqlite3_close(db);
You can easily google the functions to learn about their arguments and what they do in-detail.
To create a new database, just connect to it:
$ sqlite3 your_database_file
This will create your database in the file your_database_file. If this file already exists, the command will open it.
Then you can execute CREATE TABLE or any other SQL.

Get column names in sqlite3

I would like to print my sql table contents and for that reason, I would like to retrieve the column name from the table. One solution I came across was :
SELECT sql FROM sqlite_master WHERE tbl_name = 'table_name' AND type = 'table'
But looks like I will have to parse the results.
Another suggestion was to use:
PRAGMA table_info(table_name);
but the below sqlite page suggests not to use this :
http://www.sqlite.org/pragma.html#pragma_full_column_names
Does there exists any way to achieve this. Also what would be the syntax to use
PRAGMA table_info(table_name);
Above solutions have been taken from here
Since your question is tagged c I assume you have access to the SQLite C API. If you create a prepared statement with one of the prepare_v2 functions that selects from the table you want you can use sqlite3_column_name to get the name of each column.
You can safely use PRAGMA table_info(table-name); since it's not deprecated in any way (yours post links to another pragma).
int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
int *pnRow, /* Number of result rows written here */
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
If you are using c/c++, you can use the function sqlite3_get_table(db, query, result, nrow, ncol, errmsg);
Make the query as select * from table;
And the first few results result[0], result[1]...... will have the column names.
This setting will toggle showing column names as part of the return for select statements:
.headers on