Variable in MySQL Query causes error - mysql

I have a node.js app using node-mysql to query a MySQL database.
Problem: It appears that when I make the table name in the query a variable, things stop working. Did I miss out on something?
Working Node Code
client.query('SELECT * from tableA',
function(error, results, fields) {
if (error)
throw error;
callback(results);
});
Non-working Node Code
client.query('SELECT * from ?',
[ tableA ],
function(error, results, fields) {
if (error)
throw error;
callback(results);
});

You could probably just append the table name to the string (pseudo code, I don't know node.js)
client.query('SELECT * from ' + [tablaA],
function(error, results, fields) {
if (error)
throw error;
callback(results);
});

They reason why it's not working is pretty clear.
The query from the non-working code will be :
SELECT * from 'tableA'
A solution is the one from #Andreas, but you will have the same problem in a where statement or insert for other values you don't want to be escaped like "null" value. ( convert into a string)
Same problem here
Check out the source how format && escape from node-mysql works.

Related

nodejs throws error with mysql like query via prepared statements

Am retrieving values from database using nodejs.
I implemented mysql like query via prepared statement to ensure that sql injection attack is eliminated. my problem is that it does not retrieve any result. it just show empty results in the console please can someone point to me what is wrong with the query
exports.autosearch = function (req, res) {
//var search = req.body.searchText;
var search = 'bukatti';
//db.query('SELECT * FROM users WHERE name like ?', ['%' + search + '%'], function (error, results, fields) {
db.query('SELECT * FROM users WHERE name like ?', ['%search%'], function (error, results, fields) {
console.log(results);
});
}
Thanks
I have found out my problem. i added the error log and discover that the was type error somewhere. This fix it anyway
db.query("SELECT * FROM users WHERE name like ?", ['%' + search + '%'], function (error, results, fields) {
Thanks

Render multiple queries in Node Express

I am working with Node.js (express) and MySQL and I have had problems trying to make several queries in the same route. The error it throws is:
Can't set headers after they are sent.
And my code is this:
router.post('/test', function (req, res, next){
db.query("select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where
TABLE_NAME = 'registros';", function (error, results, fields) {
if (error) throw error;
res.render('test', {
columnNames: results
});});
db.query("SELECT * FROM registros", function (error, resp, fields) {
if (error) throw error;
res.render('test', {
dataRegistros: resp
});});
});
I understand that it may be because it is rendering twice in the same route. What would be the correct method to make several SQL queries and return them to a file in view?
Regards!
According to mysql nodejs driver you can setup it o combine the queries and return an array with results
You must set this when you create the connection:
mysql.createConnection({multipleStatements: true});
Then make the request with both queries
router.post('/test', function (req, res, next) {
var queries = [
"select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'registros'",
"SELECT * FROM registros"
];
db.query(queries.join(';'), function (error, results, fields) {
if (error) throw error;
res.render('test', {
columnNames: results[0], // First query from array
dataRegistros: resp // Second query from array
});
});
});
But let me ask a question, why would you need to query column names when actually you query all rows and can get columns from there?
To make several queries from a single route use async npm library
npm install --save async
then use parallel method and functions to make the several queries for database with the callback.
async.parallel({
one: function(callback) {
callback(null, 'abc\n');
},
two: function(callback) {
callback(null, 'xyz\n');
}
}, function(err, results) {
if (error) throw error;
res.render('test', {
columnNames: results.one,
dataRegistros: results.two
});
});

NodeJS Mysql Stop Server Crash on Error

I am using https://github.com/felixge/node-mysql
and everytime a mysql query throw an error, for example if a row does not exist. The node server crashes.
connection.connect();
connection.query('SELECT * from table1 where id = 2', function(err, rows, fields) {
if (err) console.log(err);
if (rows[0]) {
console.log('The result is ', rows[0].user);
}
});
connection.end();
How do I simply print the errors to the page rather than crash the server.
If an error occurs, your code console.log's it but tries to access rows[0] anyway. In case of errors rows will be undefined so rows[0] will trigger a new error.
Easily fixed with an else in combination with a length check:
if (err) {
console.log(err);
} else if (rows.length) {
console.log('The result is ', rows[0].user);
} else {
console.log("Query didn't return any results.");
}
I prefer to use the return statement:
connection.connect();
connection.query('SELECT * from table1 where id = 2', function(err, rows, fields) {
if (err) return console.log(err);
if (rows[0]) {
console.log('The result is ', rows[0].user);
}
});
connection.end();
This is cleaner IMO and guarantees that I wont leave anything out of an if statement block where it shouldn't.

Node Mysql Cannot Enqueue a query after calling quit

where do i close the mysql connection?
I need to run queries in sequence. I am writing code that looks like this at present:
var sqlFindMobile = "select * from user_mobiles where mobile=?";
var sqlNewUser = "insert into users (password) values (?)";
//var sqlUserId = "select last_insert_id() as user_id";
var sqlNewMobile = "insert into user_mobiles (user_id, mobile) values (?,?)";
connection.connect(function(err){});
var query = connection.query(sqlFindMobile, [req.body.mobile], function(err, results) {
if(err) throw err;
console.log("mobile query");
if(results.length==0) {
var query = connection.query(sqlNewUser, [req.body.password], function(err, results) {
if(err) throw err;
console.log("added user");
var user_id = results.insertId;
var query = connection.query(sqlNewMobile, [user_id, req.body.mobile], function(err, results) {
if(err) throw err;
console.log("added mobile");
//connection.end();
});
});
}
});
//connection.end();
(I am a beginner with node, npm-express and npm-mysql. I have tried searching SO for "express mysql cannot enqueue" to find related questions and have not found them.)
I fixed this problem use this method:
connection.end() in your connection.query function
The fixed code is here
If you're using the node-mysql module by felixge then you can call connection.end() at any point after you've made all of the connection.query() calls, since it will wait for all of the queries to finish before it terminates the connection.
See the example here for more information.
If you're wanting to run lots of queries in series, you should look into the async module, it's great for dealing with a series of asynchronous functions (i.e. those that have a callback).
Maybe the problem is that the mySQL query is executed after the connection is already closed, due to the asynchronous nature of Node. Try using this code to call connection.end() right before the thread exits:
function exitHandler(options, err) {
connection.end();
if (options.cleanup)
console.log('clean');
if (err)
console.log(err.stack);
if (options.exit)
process.exit();
}
//do something when app is closing
process.on('exit', exitHandler.bind(null, {cleanup: true}));
Code adapted from #Emil Condrea, doing a cleanup action just before node.js exits
In my case connection.end was being called in a spot that was hard to notice, so an errant call to connection.end could be the problem with this error

How to do a query to mysql database AFTER client`s request in nodejs/socket.io?

All examples i've seen were doing a query first and then send to client some info.
If I do a query FIRST and then use results in functions it works:
client.query(
('SELECT * FROM '+TABLES_USERS),
function(err, results, fields) {
var Users = (results);
io.sockets.on('connection', function (socket) {
socket.on('event1', function (data) {
var requser = Users[data];
socket.emit('event2', requser);
});
});
client.end();
});
But now i need to do a query on client's request.
I tried something like this but query doesn't work:
io.sockets.on('connection', function (socket) {
socket.on('event1', function (data) {
console.log('query required'); /*works*/
client.query(
('SELECT * FROM '+TABLES_USERS+' WHERE id_user ='+data),
function(err, results, fields) {
if (err) {throw err; /*doesn't work*/
console.log('error'); /*doesn't work*/ }
console.log('query is done'); /*doesn't work too. so i think query just doesn't work cuz there are no error and no results*/
socket.emit('event2', results);
client.end();
});
});
});
There are some things you are not doing ok (in my opinion) in the example above:
1) You don't ask for login after the client is connected to Socket.IO, instead you check to see if his session contains data that can verify is he's connected.
You should read the article about Express, Socket.IO and sessions., since it explains everything in detail (if you are using Express)
2) I think MongoDB, CouchDB and possibly other databases are better suited for realtime applications than MySQL.
I've solved the problem by using node-mysql-libmysqlclient instead of node-mysql. But if someone knows a way to do a query AFTER client's request in node-mysql, please tell me))