can I call a function inside an MySQL Query? To ask more elaborately consider I have a function which returns the account_id of the customer
int return_account_id(){
return (account_id);
}
Now can I call this function inside my query ? Is it possible ?
`resultset = statement->executeQuery("SELECT `account_id`, `acc_name` FROM `account` WHERE `account_id` = "return_account_id()" ");
Why not this:
#include <sstream>
stringstream query;
query << "SELECT * FROM account WHERE account_id = " << return_account_id() << ";";
resultset = statement->executeQuery(query.str());
Not really. Remember, your C++ code is application code. The SQL statement is server code, potentially running on a different machine.
But, the answer is not "No". You can add user defined functions that MySQL knows about. If you need to do this, the place to start is here.
Related
i am using Qt and i have written c++ code,i have already connected with sqlite database.i want to insert name in database
std::string name="Hello";
qry.prepare( "INSERT INTO s_no (Name,Status) VALUES ('name','1' )");
if( !qry.exec() )
qDebug() << qry.lastError();
else
qDebug( "Inserted!" );
but in db i am finding name only , not hello;
please help me..thank you so much in advance
C++ and SQL are two different programming languages, and execute in different environments. This means that C++ objects are not visible in SQL.
In theory, it would be possible to construct the string containing the SQL command so that the value of the name variable is inserted directly into it:
qry.prepare("INSERT INTO s_no (Name,Status) VALUES('" + name + "', '1')"); // don't do this
However, this will blow up if the name contains a quote. Escaping quotes would be possible with additional code, but a better way of getting variable values into an SQL query is to use parameters:
qry.prepare("INSERT INTO s_no (Name,Status) VALUES(?, '1')");
qry.bindValue(0, name);
(This is the only sensible way of using blob values in a query.)
Try making name a QString. You can change std::string to QString by using: QString name2 = QString::fromStdString(name);. Don't forget to include: #include <QString>.
Using Qt, I have to connect to a database and list column's types and names from a table. I have two constraints:
1 The database type must not be a problem (This has to work on PostgreSQL, SQL Server, MySQL, ...)
2 When I looked on the internet, I found solutions that work but only if there are one or more reocrd into the table. And I have to get column's type and name with or without record into this database.
I searched a lot on the internet but I didn't find any solutions.
I am looking for an answer in Qt/C++ or using a query that can do that.
Thanks for help !
QSqlDriver::record() takes a table name and returns a QSqlRecord, from which you can fetch the fields using QSqlRecord::field().
So, given a QSqlDatabase db,
fetch the driver with db.driver(),
fetch the list of tables with db.tables(),
fetch the a QSqlRecord for each table from driver->record(tableName), and
fetch the number of fields with record.count() and the name and type with record.field(x)
According to the previous answers, I make the implementation as below.It can work well, hope it can help you.
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSLITE", "demo_conn"); //create a db connection
QString strDBPath = "db_path";
db.setDatabaseName(strDBPath); //set the db file
QSqlRecord record = db.record("table_name"); //get the record of the certain table
int n = record.count();
for(int i = 0; i < n; i++)
{
QString strField = record.fieldName(i);
}
}
QSqlDatabase::removeDatabase("demo_conn"); //remove the db connection
Getting column names and types is a database-specific operation. But you can have a single C++ function that will use the correct sql query according to the QSqlDriver you currently use:
QStringlist getColumnNames()
{
QString sql;
if (db.driverName.contains("QOCI", Qt::CaseInsensitive))
{
sql = ...
}
else if (db.driverName.contains("QPSQL", Qt::CaseInsensitive))
{
sql = ...
}
else
{
qCritical() << "unsupported db";
return QStringlist();
}
QSqlQuery res = db.exec(sql);
...
// getting names from db-specific sql query results
}
I don't know of any existing mechanism in Qt which allows that (though it might exist - maybe by using QSqlTableModel). If noone else knows of such a thing, I would just do the following:
Create data classes to store the information you require, e.g. a class TableInfo which stores a list of ColumnInfo objects which have a name and a type.
Create an interface e.g. ITableInfoReader which has a pure virtual TableInfo* retrieveTableInfo( const QString& tableName ) method.
Create one subclass of ITableInfoReader for every database you want to support. This allows doing queries which are only supported on one or a subset of all databases.
Create a TableInfoReaderFactory class which allows creation of the appropriate ITableInfoReader subclass dependent on the used database
This allows you to have your main code independent from the database, by using only the ITableInfoReader interface.
Example:
Input:
database: The QSqlDatabase which is used for executing queries
tableName: The name of the table to retrieve information about
ITableInfoReader* tableInfoReader =
_tableInfoReaderFactory.createTableReader( database );
QList< ColumnInfo* > columnInfos = tableInfoReader->retrieveTableInfo( tableName );
foreach( ColumnInfo* columnInfo, columnInfos )
{
qDebug() << columnInfo.name() << columnInfo.type();
}
I found the solution. You just have to call the record function from QSqlDatabase. You have an empty record but you can still read column types and names.
How do I use LIKE with Pro*C? The code below doesn't work. I need to search records in database.
cout<<"Employee name\t\t: ";
cin.getline(name,50);
EXEC SQL SELECT NAME INTO :nameResult FROM EMPLOYEE WHERE NAME LIKE '%:name%';
Declare a host variable like this: "char hLikeVar[64];". Then string copy "%[empl name]%" into it. For [empl name] use the input you got from the user. Then you can do this:
... WHERE NAME LIKE :hLikeVar;
so Pro * C provides varchar structures, where you aren't required to handle many things. So if you are declaring
varchar LikeVar[Length_of_Variable];
and use
strcpy(LikeVar.arr); /* .arr is the character array */
LikeVar.len = strlen(LikeVar.arr);
after this you can use directly: with in the sql statement.
I'm just getting started implementing some client software for a PostgreSQL database.
The queries will allow input parameters that come from an untrusted source. Therefore I need to sanitize my transactions before actually commiting them.
As for libpq I've found PQescapeStringConn, that may do want I need. However, as my code will be written in C++, I'd prefer to use a libpqxx equivalent. I could not find anything related. (Except probably the Escaper, which however lies in the internal namespace...)
I'd appreciate any suggestions on best practices, reading, links to the documentation, whatever.
Using pqxx::transaction_base::quote is the way to go.
Here's a simple example:
// connection to the database
std::string login_str = "TODO: add credentials";
pqxx::connection conn(login_str);
pqxx::work txn(conn);
// a potentially dangerous input string
std::string input = "blah'; drop table persons; --";
// no proper escaping is used
std::string sql_1 = "select * from persons where lastname = '%s'";
std::cout << boost::format(sql_1) % input << std::endl;
// this is how it's done
std::string sql_2 = "select * from persons where lastname = %s";
std::cout << boost::format(sql_2) % txn.quote(input) << std::endl;
The output is:
select * from persons where lastname = 'blah'; drop table persons; --'
select * from persons where lastname = 'blah''; drop table persons; --'
For reference:
http://pqxx.org/devprojects/libpqxx/doc/development/Reference/a00196.html#details
Actually in order to give a better view, I was having an issue with this kind of things this week and we started using std::string pqxx::transaction_base::esc
You just have to add it in the argument you going to insert or update, and it will do the job.
The quote function mentioned up there, its add the quote to the argument, but it does not fix the problem.
For example; if you do something like UPDATE person set name = w.quote(name) where id = 1;
There you are using the quote correctly in order to put between quotes the argument.
So in order to insert a single quote or avoid SQL Injection, you have to do:
UPDATE person set name = + "'" + w.esc(name) + "'" where id = 1 OR
UPDATE person set name = w.quote(w.esc(name)) where id = 1;
Being W the pqxx::work variable already initialized with the connection to the database.
We were using stringstream to prepare select queries in C++. But we were strongly advised to use QUERY PARAMETERS to submit db2 sql queries to avoid using of stringstream. Can anyone share what exactly meant by query parameter in C++? Also, share some practical sample code snippets.
Appreciate the help in advance.
Edit: It is stringstream and not strstream.
Thanks,
Mathew Liju
I suspect this refers to parameterized queries in general, rather than constructing the query in a string, they supply sql variables (or parameters) and then pass those variables separately. These are much better for handling SQL Injection Attacks. To illustrate with an example:
"SELECT * FROM Customers WHERE CustomerId = " + _customerId;
Is bad, while this:
"SELECT * FROM Customers where CustomerId = #CustomerId"
is good. The catch is that you have to add the parameters to the query object (I don't know how this is done in C++.
References to other questions:
https://stackoverflow.com/questions/1973/what-is-the-best-way-to-avoid-sql-injection-attacks
Stored Procedures vs Parameterized Queries
Wild Wild Web:
http://www.justsoftwaresolutions.co.uk/database/database-tip-use-parameterized-queries.html
Sql query in parameterized query form is safe than string format to avoid sql injection attack.
Example of parameterized query
StringBuilder sqlstr = new StringBuilder();
cmd.Parameters.AddWithValue("#companyid", CompanyID);
sqlstr.Append("SELECT evtconfigurationId, companyid,
configname, configimage FROM SCEVT_CONFIGURATIONS ");
sqlstr.Append("WHERE companyid=#companyid ");
Example of query string format
StringBuilder sqlstr = new StringBuilder();
sqlstr.Append("SELECT evtconfigurationId, companyid, configname,
configimage FROM SCEVT_CONFIGURATIONS ");
sqlstr.Append("WHERE companyid" + CompanyID);