How to use AND operator in mysql with Express framework - mysql

I want to implement a query using AND operator in express framework using mysql.
mysql query: select * from questions where question_id=1 AND answer="apple" AND appkey="1122";
I want to implement the above query in express js using mysql. I have tried the below query.
req.getConnection(function(err,connection){
var data = {
qid : input.questionid,
ansvalue : input.answervalue,
appid : input.appkey,
};
console.log(data);
var query = connection.query('SELECT * FROM request_auth WHERE question_id = ?',[qid]'AND answer_description = ?',[ansvalue]'AND app_key = ?',[appid],function(err,rows)
{
if(query=='')
console.log("Error Selecting : %s ",err );
res.render('edit_customer',{page_title:"Edit Customers - Node.js",data:rows});
});
but it is throwing error qid is not defined. Please give me solution for this. Thank you.

You have to separate the actual query (with placeholders) and the placeholder parameters (see third example here):
connection.query('SELECT * FROM request_auth WHERE question_id = ? AND answer_description = ? AND app_key = ?', [qid, ansvalue, appid], ...)
Also, be sure that you're calling connection.release() when the query is done (more info here).

I'm just throwing out a potential quick fix since I haven't worked with this framework before but you may need to add spaces before where your variables are being used because it seems it may not be using AND as it is seeing it as one long word.

Related

Node.js: MySQL query with multiple variables

I'm writing a node/express application, using mysql as a database.
One question upfront, that i can't really figure out yet: Is it possible to make multiple querys in one route?
Nevertheless, my problem is, that i want to use multiple variables in the database-query as follows, which does not work.
router.get('/:route_name', (req, res) => {
const route_name = req.params.route_name;
const route_name_join = req.params.route_name+".comp_id";
const queryhelper = [route_name, route_name_join];
const dbquery = "SELECT * FROM ? INNER JOIN users ON ? = users.id;";
sqldb.query(dbquery, queryhelper, function (err, result, fields) {
if (err) throw err;
res.render('categories/category',{
items : result
});
console.log(JSON.stringify(result));
});
I'm expecting to, for example in case of
.../categories/customers
"SELECT * FROM customers INNER JOIN users ON customers.comp_id = users.id;".
If i type in exactly that into dbquery, it does work, but as soon as i'm doing it using '?', i get an error that i'm having a mistake in my mysql syntax at
"SELECT * FROM 'customers' INNER JOIN users ON 'customers.comp_id' = users.id;"
I assume that there is a problem at customers.comp_id, but i simply can't figure out how to fix it.
You need to perform string substitution for this. Parameters can only be used for expressions -- they're replaced with the supplied value as a literal. You can't use a parameter to supply a table or column name.
So do:
const dbquery = `SELECT * FROM ${route_name} INNER JOIN users ON ${route_name_join} = users.id;`;
If these variables are coming from user input, make sure you whitelist them before using them in the query, to prevent SQL-injection.

nodejs express mysql query with 'SET #'XXX''

I am working on nodejs/express app. In my routes i need to query data from MySQL database. It's working fine with exceptions for the queries that have parameters in them.
Any query without parameters work as expected:
SELECT * FROM table WHERE col = 'b'
But the one below returns undefined
SET #a = 'b'
SELECT * FROM table where col = #a
I generate string for queries in separate function (not sure if that makes any difference).
Any help will be greatly appreciated.
I think you may be looking for the ? placeholder method, described at
https://www.w3schools.com/nodejs/nodejs_mysql_where.asp
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ?';
con.query(sql, [adr], function (err, result) {
  if (err) throw err;
  console.log(result);
});
There's also multiple placeholders too, passed in as an array:
var name = 'Amy';
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE name = ? OR address = ?';
con.query(sql, [name, adr], function (err, result) {
  if (err) throw err;
  console.log(result);
});

Escaping knex mysql query statements

I'm fairly new to knex and databases in general, so this is a beginner question.
I found no clear mention in the knex docs about this.
Are non-raw knex queries automatically "safe"?
Secondly, for raw queries, I have several raw statements similar to this:
var condition = _.map(ids, function(id) {
return '`id`=' + id;
}).join(' OR ');
knex('categories')
.whereRaw(condition)
.select('*')
.catch(_error.bind(null, cb))
.then(function(res) { ... });
Would escaping the id in the condition with a function described here be sufficient to escape that query?
What else to look out fo in such a scenario?
All knex queries are safe, also the knex.raw() queries if you use parameter binding syntax where ? are replaced with escaped values (http://knexjs.org/#Raw).
Query that you are doing would be better be done without raw as follows
knex('categories').whereIn('id', ids).catch(...).then(...);
If you want to use automatic escaping of column reference a.k.a identifier you may use whereRaw('?? = ?', ['id', value]) which escapes first part as identifier and second part as value.
So with parameter escaping your example would be something like this:
var condition = _.map(ids, function() {
return '?? = ?';
}).join(' OR ');
var conditionParameters = _.flatten(_.map(ids, function(id) {
return ['id', id];
}));
knex('categories')
.whereRaw(condition, conditionParameters)
.select('*')
.catch(_error.bind(null, cb))
.then(function(res) { ... });
However I have to say that there is pretty much always better ways to do the queries in knex than using raw conditions made this way.

JugglingDB custom query

I am trying to figure how to create a "repository" file (for the symfony2 users) where i will put all my special behaviour queries.
I have a simple db shema with :
User (email)
RelationType (name)
UserXUserXRelation (fromUser, toUser, relation)
I want to retrieve the user with relation X on my user Y, so in sql it will looks like :
var sql = 'SELECT u.email, u.id
FROM user u
INNER JOIN UserXUser uxu ON uxu.toUser_id = u.id
WHERE uxu.relation_id = 1 AND uxu.fromUser_id = '+id
Where should i create this method ? I tried in the db/shema.js and app/models/user.js without success.
I found here Using arbitrary mySQL Query with JugglingDB? that i should use the shema object to use "query", where and how could I use it ?
Does the callback will look like this :
function(err, data) {...}
Is there some best practice about code separation in that case ?
Additional question : is there a way to bind parameters the PHP PDO way with jugglingdb ?
Thanks for all.
It is possible to execute any arbitrary query using jugglingdb and compoundjs. Providing you are using compoundjs, you can just use the compound.models.user.schema.adapter.query(). The compound object should be parsed into your user model, meaning you have access to many other methods. The way you would use this query in your model would be by creating a method inside the users model with the following code:
var sql = 'SELECT u.email, u.id
FROM user u
INNER JOIN UserXUser uxu ON uxu.toUser_id = u.id
WHERE uxu.relation_id = 1 AND uxu.fromUser_id = '+id
compound.models.user.schema.adapter.query(sql, function(err, data) {
if(error) {
console.log(error)
} else {
//Enjoy your data
}
})
As this overrides the jugglingdb quote escaper, beware of sql injection, make sure your id variable is checked and sanitised.

Propel ORM - Custom where clause

I'm trying to match md5(ID) to an id.
SELECT *
FROM `user` u
WHERE
MD5(`user_id`) = '66f041e16a60928b05a7e228a89c3799'
this is ID = 58
I tried something like this. I know I'm close I just don't know what I'm missing
$criteria = new Criteria();
$criteria->addAnd('md5('.User::USER_ID.')', $_REQUEST['fs'], Criteria::CUSTOM);
$user = UserPeer::doSelectOne($criteria);
Any ideas?
First of all, directly using Criteria objects is deprecated not recommended. You should use Active Query classes.
Using these classes, you will be able to write stuff like this :
UserQuery::create()
->where('md5(User.Password) = ?', $_REQUEST['fs'], PDO::PARAM_STR)
->findOne();
You'll notice that I use the PhpName both of the table and the column in the query.
EDIT : For raw conditions, the parameter type has to be specified. You'll find more information on this issue.
After lenghty T&E process I managed to get it done like this
$c = new Criteria();
$c->add(UserPeer::USER_ID, "md5(user.user_id) = \"".$_REQUEST['fs']."\"", Criteria::CUSTOM); // risk of SQL injection!!
$saved_search = UserPeer::doSelectOne($c);
For some reason PropelORM though that $_REQUEST['fs'] was name of the table rather than the value. \"" solved the problem.