Node.js MySQL query error ER_PARSE_ERROR - mysql

I have a problem with a MySQL query inside of a NodeJS application. In my snippet I loop through a triple-nested for cycle and save some different data in the post variable. What I want to do is checking whether this data already exists into the database and, if not, execute an INSERT query.
Been trying in any possible way, however I get the following error:
Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' `user_id` = '421', `product_id` = '1', `brick_id` = '1', `effect_date` = '2016-' at line 1
I don't think there are any SQL errors, I have been checking a thousand of times but maybe I am missing something. This is what I tried to do:
router.post('/relations/finalize', function (req, res, next) {
// Executing a cycle for every possible data combination
for (var i = 0; i < req.body.users_selection.length; i++) {
for (var j = 0; j < req.body.products_selection.length; j++) {
for (var k = 0; k < req.body.bricks_selection.length; k++) {
post = {
owner_id: req.session.userid,
user_id: req.body.users_selection[i],
product_id: req.body.products_selection[j],
brick_id: req.body.bricks_selection[k],
effect_date: req.body.year + "-" + req.body.month + "-01 00:00:00",
}
// Checking if the entry already exists
req.app.locals.connection.query({
sql: 'SELECT * FROM relations WHERE user_id = ? AND product_id = ? AND brick_id = ? AND effect_date >= ?',
timeout: 40000, // 40s
values: [post]
}, function (err, rows, fields) {
if (err) throw err;
else {
if (rows.length > 0) {
console.log("The entry already esists");
} else {
req.app.locals.connection.query("INSERT INTO relations SET ?", post, function (err, row, fields) {
if (err) throw err;
else {
console.log("The entry didn't exists and was then created.");
//res.redirect("/relations/wizard");
}
});
}
}
});
}
}
}
});
Any help will be greatly appreciated to solve this issue.
EDIT: I also tried to pass separate values into the SELECT query, like this:
values: req.body.users_selection[i], req.body.products_selection[j], req.body.bricks_selection[k], req.body.year + "-" + req.body.month + "-01 00:00:00"
But the result I get is that the INSERT query is called X times with the same values, as the for loops are not going through, maybe because of the asynchronous nature of Node..

Related

Cannot get variable from sql query in Node

Sorry, I read about handling async functions in order to get variable names from them but I am not sure what I am doing wrong and how to handle it.
for(let j = 0; j < ga.length; j++) {
var sql = "SELECT * FROM matches WHERE clh = '"+ga[j]+"'"
const dbq = db.query(sql, function(err, result) {
if (err) console.log(err);
var gs1 = 0;
var gs2 = 0;
var pts1 = 0;
var w1 = 0;
var d1 = 0;
var l1 = 0;
for (let i = 0; i < result.length; i++) {
gs1 += result[i].gsh;
gs2 += result[i].gsa;
const r = mgs1(result[i].gsh, result[i].gsa);
if (r == 3) w1 += 1;
if (r == 1) d1 += 1;
if (r == 0) l1 += 1;
var gd1 = gs1 - gs2;
var r1 = [result[i].clh, result.length, w1, d1, l1, gs1, gs2, gd1 ];
}
gs4.push(r1);
if (gs4.length == 6) {
return gs4;
}
})
}
}
This function returns the array that I want but I am not sure how to access it outside the db.query block. I read posts about handling variables from async functions but I just can't seem to do it in this example. Thanks a lot in advance
I guess you have defined const gs4 = [] somewhere in code you did not show us. That's part of the answer to your question: it will be populated after your callback from db.query() completes.
The rest of the answer: it is not populated until after the callback completes. Also, the return from inside your callback is meaningless; it just returns to db.query() .
Also, db.query() returns to its caller instantly, long before it calls its callback. So your loop tries to run multiple queries concurrently. I guess the result in gs4 will accumulate the results from all the queries.
With respect, I believe a quick jump up the learning curve for Promises or async / await lies in your near future.
This may help : node.js mysql query in a for loop
If you would like to query the database the correct way, you should use the embedded functions that comes with database driver. For string interpolation and returning data for your functions.
exports.lookupLogin = (req, res, next) => {
let sql = 'SELECT e.employee_id, e.login, e.password FROM employee e WHERE e.login=?';
postgres.client.query(sql, [req.body.login], (error, result, fields) => {
if (err) {
return res.status(500).json({ errors: ['Could not do login'] });
}
res.status(200).json(result.rows);
});
};
For more information you can check the mysql documentation to use with nodejs.

Return boolean value from MYSQL in NodeJS

Im working on a function which will return a boolean-value. This value represents if an user exists in the database. Currently I have this:
function checkIfExists(){
var sql = "SELECT * FROM Users WHERE user = " + mysql.escape(req.body.username);
var rows = 0;
database.query(sql, function(err, result, fields){
console.log(result.length);
rows += result.length;
});
return rows > 0;
}
console.log(checkIfExists());
I use 'console.log(result.length)' to validate if there are results. When I test some input, I got this:
false
1
This is strange because there is one result, so rows should be equal to 1. But then it returns false instead of true. Is it possible that the value of rows isn't changed in 'database.query(...' ?
Because your function checkIfExists is asynchronous, I think you sould use callback system like this :
function checkIfExists(callback) {
var sql = "SELECT * FROM Users WHERE user = " + mysql.escape(req.body.username);
var rows = 0;
database.query(sql, function (err, result, fields) {
if (err) {
callback(err, null);
}
else {
console.log(result.length);
rows += result.length;
callback(null, rows > 0);
}
});
}
checkIfExists(function(err, isExists) {
if (err) {
// An error occured
}
else {
console.log(isExists);
}
});
EDIT
You also can simlify your checkIfExists function like this :
function checkIfExists(callback) {
var sql = "SELECT * FROM Users WHERE user = " + mysql.escape(req.body.username);
database.query(sql, function (err, result) {
callback(err, result ? result.length > 0 : false);
});
}
More information here :
Understanding Async Programming in Node.js
Hope it helps.

Node JS mySQL tripple query and lost of information

In my application I have a two different tables related to each other by ID of the first one (one to many relation). It should first collect the data from the frontend-side by in JSON format which looks like this:
cancellation = {
name: someting
id: someting
rule =
[
{someting}, {something}, {something}
]
}
One table would be for cancellation and the second one for the rules. If I want to put those information in this order I need first insert one record for cancellation. Then make a query to find out what is an ID of this record in the database and after that insert all rules using this ID as a foreign key. But since Node JS is asynchronous before I fetch the information about the ID of the record program stars to execute rest of the code and consider this variable as undefined.
app.post('/databaseSend/cancellation', function(req,res){
var cancellationReceived = req.body;
var cancellationID;
var rules = [];
var cancellation = [];
cancellation[0] =
[
cancellationReceived.name,
cancellationReceived.id
]
// inserting data into cancellation table
connection.query("INSERT INTO cancellations (name, User_ID) VALUES ?", [cancellation],
function(err,results){
if(err){console.log(err)}
}
)
//fetching ID of the current record
connection.query("SELECT id FROM cancellations WHERE User_ID = ? AND name = ?", [cancellationReceived.id, cancellationReceived.name],
function(err, results){
var cancellationID = results[0].id;
});
//assigning ID to use it as a foreign key
for(var i = 0; i < cancellationReceived.rule.length; i++)
{
rules[i] =
[
cancellationReceived.rule[i].daysBefore,
cancellationReceived.rule[i].fee,
cancellationReceived.rule[i].type,
cancellationID
]
}
for(var i = 0; i < rules.length; i++)
{
console.log(rules[i]); // ID is undefined
}
});
How can I solve this problem? I tried to use setTimeout for pausing my code but it did not change anything.
And I use this node module for mysql - > https://github.com/mysqljs/mysql
The best way to solve this problem is RTFM.
connection.query('INSERT INTO cancellations (name, user_id) values ?', [cancellation], function(err, results) {
if (err)
return console.error(err);
// See https://github.com/mysqljs/mysql#getting-the-id-of-an-inserted-row
var cancellation_id = results.insertId;
// Generate sql for rules, join them by ; and execute as one query
// See https://github.com/mysqljs/mysql#multiple-statement-queries
connection.query(sqls, function(err) {
if (err)
return console.error(err);
// Send response here
});
})

Nodejs MySQL ER_PARSE_ERROR on VALID query

I've tried using mysql lib with nodejs and a simple query like SELECT * FROM table; works, but now that I've tried to construct a real query to update my database it doesn't work.
I have used an online validating tool and it checks out.
var mysql = require('mysql');
var request = require('request');
request.get('http://localhost:8080/dump/asda.dump', function (error, response, body) {
if (!error && response.statusCode == 200) {
var data =JSON.parse(body);
var products = data['products'][0];
var myquery = "INSERT INTO `products2` (";
var midquery = ") VALUES (";
for (var k in products) {
if (typeof products[k] === 'number') var v = products[k];
else if (typeof products[k] === 'string') var v = "\'" + products[k]+ "\'";
else if (typeof products[k] === 'boolean') var v = products[k];
else continue;
myquery = myquery + "`" + k + "`,";
midquery = midquery + v + ",";
}
myquery = myquery.slice(0,-1);
midquery = midquery.slice(0, -1);
print(myquery + midquery + ")");
connection.connect();
connection.query(myquery, function (err, rows, fields) {
if (!err) console.log(rows);
else console.log(err);
});
connection.end();
}
});
I have tried both the version with the ticks and without the ticks an none of them work.
Possible reasons might be
Too long query. Maybe some internal char limit exeeded?
Unsupporded characters. I am pretty sure I have quite a few Croatian ćčćš in there. How to I support that?
Improper ' " escaping (although it seems ok to me).
I have 'code' as a table column. I've checked and it's not a reserved keyword in mysql but it's blued in MySQL Workbench so maybe it breaks things somehow.
What I get is:
{ [Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right syntax to
use near '' at line 1]
code: 'ER_PARSE_ERROR',
errno: 1064,
sqlState: '42000',
index: 0 }
You should try with the ticks whenever you are using the database entities inside the query like the table names or database variables. As far as your query is concerned, only myquery is getting into the function as your database statement and it doesn't contain the whole query. As a result you are getting an error because of your incomplete complete query and improper syntax in it(as it is incomplete already). Your print statement will print it right because of the concatenation that you have used. If you are able to keep the concatenated query string in a variable such as:
var new_query=myquery + midquery + ")";
And then using it as
connection.query(new_query, function (err, rows, fields) {
if (!err) console.log(rows);
else console.log(err);
});
I think your query should work. Thank you...!

How to save the result of MySql query in variable using node-mysql [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 1 year ago.
im trying to save the result of MySql query in variable using node-mysql model and node.js so i have this code:
connection.query("select * from ROOMS", function(err, rows){
if(err) {
throw err;
} else {
console.log(rows);
}
});
and the result is :
[ { idRooms: 1, Room_Name: 'dd' },
{ idRooms: 2, Room_Name: 'sad' } ]
so i need to store this results in variable so i try like this:
var someVar = connection.query("select * from ROOMS", function(err, rows){
if(err) {
throw err;
} else {
return rows;
}
});
console.log(someVar);
but is not working thanks for any help in advance.
Well #Fadi, connection.query is async, which mean when your call your console.log(someVar), someVar has not been set yet.
What you could do:
var someVar = [];
connection.query("select * from ROOMS", function(err, rows){
if(err) {
throw err;
} else {
setValue(rows);
}
});
function setValue(value) {
someVar = value;
console.log(someVar);
}
You can't do that because network i/o is asynchronous and non-blocking in node.js. So any logic that comes afterwards that must execute only after the query has finished, you must place inside the query's callback. If you have many nested asynchronous operations you may look into using a module such as async to help better organize your asynchronous tasks.
As a complement to already given answers.
var **someVar** = connection.query( *sqlQuery*, *callback function( err , row , fields){}* )
console.log(**someVar**);
This construction will return in someVar information of this connection and his SQL query . It will not return values ​​from the query .
Values ​​from the query are located in the callback function ( err , row , fields)
Here is your answer if you want to assign a variable to res.render
//before define the values
var tum_render = [];
tum_render.title = "Turan";
tum_render.description = "Turan'ın websitesi";
//left the queries seperatly
var rastgeleQuery = "SELECT baslik,hit FROM icerik ORDER BY RAND() LIMIT 1";
var son5Query = "SELECT baslik,hit FROM icerik LIMIT 5";
var query_arr = [rastgeleQuery, son5Query];
var query_name = ['rastgele', 'son5'];
//and the functions are
//query for db
function runQuery(query_arr,sira){
connection.query(query_arr[sira], function(err, rows, fields) {
if (err) throw err;
var obj = [];
obj[query_name[sira]] = rows;
sonuclar.push(obj);
if (query_arr.length <= sira+1){
sonuc();
}else{
runQuery(query_arr, sira+1);
}
});
}
//the function joins some functions http://stackoverflow.com/questions/2454295/javascript-concatenate-properties-from-multiple-objects-associative-array
function collect() {
var ret = {};
var len = arguments.length;
for (var i=0; i<len; i++) {
for (p in arguments[i]) {
if (arguments[i].hasOwnProperty(p)) {
ret[p] = arguments[i][p];
}
}
}
return ret;
}
//runQuery callback
function sonuc(){
for(var x = 0; x<=sonuclar.length-1; x++){
tum_render = collect(tum_render,sonuclar[x]);
}
console.log(tum_render);
res.render('index', tum_render);
}