i have a select query to a local database and for some reason the following error shows up:
ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FROM site WHERE name = OCC AND date_start = 2018-07-30 08:00:00 AND date_end = '' at line 1
here's my query:
connection.query("SELECT *, FROM shop WHERE name = " + shop_name + " AND date_start = " + myDate + " AND date_end = " + myDate2, function (err, result)
{
if (err)
{
console.log("Error Is:" + err);
}
else
{
console.log('DATA EXISTING IS =' + JSON.stringify(result));
}
});
am i missing something?
The usual mantra: use parameterized queries. They will prevent SQL injections and make your service more secure. Furthermore they will take care of the usual pitfalls when building a query using string concatenation.
Let's have a look at your query
"SELECT *, FROM shop WHERE name = " + shop_name + " AND date_start = " + myDate + " AND date_end = " + myDate2
Which spells out to something like
SELECT *, FROM shop WHERE name = myshop AND date_start = 2018-07-30 AND date_end = 2018-08-10
There are at least 3 errors
The , behind the SELECT * this is also the one the error tells you about. I suppose you had a column list and replaced it with *
The shop name column is most certainly some char column. So you have to enclose your values with quotes
Also the dates must be used with quotes, so the SQL engine will parse it to a date and do the comparison. For some SQL engines there is also a special annotation for dates. Have a look in the documentation.
This query should work
"SELECT * FROM shop WHERE name = '" + shop_name + "' AND date_start = '" + myDate + "' AND date_end = '" + myDate2 +"'"
depending on what myDate and myDate2 are.
At least problems 2 and 3 would not happen if you use parameterized queries. Consult the documentation of the library you are using.
Related
I am currently facing this issue when summing fields. I am using Knex and Mysql.
When using Knex, I get this result for the LastYr column..
Knex Result:
But doing the same query in Mysql Workbench, I get this (which is what I want)
Mysql Workbench:
My query is this:
SELECT t1.*, IFNULL(t2.TotalUnits,0) AS TotalUnits, ROUND(IFNULL(t2.totalRevenue,0),0) AS TotalRevenue FROM (SELECT BranchDept, ForPeriod, SUM(SysGen) AS Gen, SUM(UserInput) as Live, SUM(PrevYear) AS LastYr, SUM(SysGen) - SUM(UserInput) AS Input FROM tbl_demand_forecast_details WHERE BranchDept='" + req.body.branchdept + "' AND ForPeriod >= '" + fystart + "' " +
"AND ForPeriod <= '" + fyend + "' GROUP BY BranchDept, ForPeriod " +
"ORDER BY ForPeriod) AS t1 " +
"LEFT OUTER JOIN " +
"(SELECT BranchDept, AsOfPeriod, SUM(UnitSales) AS totalUnits, SUM(PesoSales) AS totalRevenue FROM tbl_sales_history " +
"WHERE BranchDept='" + req.body.branchdept + "' AND AsOfPeriod >= '" + fystart + "' AND AsOfPeriod <= '" + fyend + "' GROUP BY AsOfPeriod) AS t2 " +
"ON t1.BranchDept = t2.BranchDept AND t1.ForPeriod = t2.AsOfPeriod
It seems knex is adding the previous value to the next in the LastYr column.
I tried this with knex.raw and using the knex methods, and I still get the wrong values.
This is driving me nuts for the past two days. Anyone point me to the right direction?
Okay. I finally got it.
The SUM query goes haywire when there are null values on the column being summed. Replacing those with zeroes fixed this issue.
My sequelize query always returns 0 results,
but when I copy/paste the exact same query into psql it works fine, returning the correct rows exactly as expected
return sequelize.query(
"SELECT * FROM orders" +
" INNER JOIN sizes ON orders.sizeid = sizes.sizeid" +
" INNER JOIN types ON sizes.typeid = types.typeid" +
" INNER JOIN items ON types.itemid = items.itemid" +
" WHERE orders.fbid = :fbid AND pickuptime >= :today" +
" ORDER BY orders.pickuptime ASC",
{ replacements: {fbid, today}, type: sequelize.QueryTypes.SELECT }
);
fbid is an integer & today is a string of shape 'yyyy-mm-dd'
If I drop the 'today' condition, I get rows returned
Is sequelize escaping my date string?
If you defined named parameter like it fbid=:fbid in the SQL script,
you should pass an object {fbid: 'fbid_value'},
or if you defined unnamed parameters fbid=?, you should pass an array ['fbid_value'].
Here's docs http://docs.sequelizejs.com/en/latest/api/sequelize/#querysql-options-promise
Try to pass an object to replacement:
return sequelize.query(
"SELECT * FROM orders" +
" INNER JOIN sizes ON orders.sizeid = sizes.sizeid" +
" INNER JOIN types ON sizes.typeid = types.typeid" +
" INNER JOIN items ON types.itemid = items.itemid" +
" WHERE orders.fbid = :fbid AND pickuptime >= :today" +
" ORDER BY orders.pickuptime ASC",
{ replacements: {fbid: 'fbid_value', today: 'today_value'}, type: sequelize.QueryTypes.SELECT }
);
I am trying to convert this:
var query_string = 'SELECT protein_A, protein_B, PIPE_score, site1_A_start FROM ' + organism + PIPE_output_table +
' WHERE ' + score_type + ' > ' + cutoff['range'] + ' AND protein_A = "' + item + '" ' +
'UNION SELECT protein_A, protein_B, PIPE_score, site1_A_start FROM ' + organism + PIPE_output_table +
' WHERE ' + score_type + ' > ' + cutoff['range'] + ' AND protein_B = "' + item + '";';
db.each(query_string, function (err, row) {
...
To this:
var query_string = "SELECT protein_A, protein_B, PIPE_score, site1_A_start FROM $table WHERE $score_type > $score AND protein_A = '$protein'" +
" UNION SELECT protein_A, protein_B, PIPE_score, site1_A_start FROM $table WHERE $score_type > $score AND protein_A = '$protein'";
var placeholders = {
$table: organism + PIPE_output_table,
$score_type: score_type,
$score: cutoff['range'],
$protein: item
};
var stmt = db.prepare(query_string, placeholders, function(err) {
console.log(err);
stmt.each(function(err,row) {
...
})
}
but I keep getting this error:
Error: SQLITE_ERROR: near "$table": syntax error
But I am not sure what is syntactically wrong here since the format is as I have seen it in the API documentation. I have tried '?', '#', and ':' before each variables but none seem to be recognized.
What's wrong in my code?
Bind parameters only work for values in the WHERE clause. Table and column names (collectively called "identifiers") won't work.
"SELECT foo FROM bar WHERE this = $that" # OK
"SELECT foo FROM bar WHERE $this = 'that'" # Not OK
Normally you'd work around this by escaping and quoting identifiers and inserting them into the query. A good database library has a method call for this...
var this = db.quote_literal(input_column);
'SELECT foo FROM bar WHERE ' + this + ' = ?'
Unfortunately, node-sqlite3 doesn't appear to have one. :(
SQLite does provide a quoting function, the %w operator, but node-sqlite3 doesn't appear to make it available.
You'll have to write your own. Follow the instructions from this answer in Python and convert them to Javascript.
Ensure the string can be encoded as UTF-8.
Ensure the string does not include any NUL characters.
Replace all " with "".
Wrap the entire thing in double quotes.
I'm not very good with Javascript, so I'll leave you to code that.
I'm getting parse errors when I try to use node-mysql to invoke a query on a MYSQL database. I'm pretty sure that the query works. It runs without doubt via phpmyadmin.
Message.save = function(message, callback){
db.query("INSERT INTO e_message (chatid, message, userid) VALUES(" + message.chatid + ", '" + message.message +"', " + message.userid + "); SELECT * FROM e_message WHERE chatid = " + message.chatid + " ORDER BY timestamp DESC LIMIT 0, 1;",
function(err, rows, fields){
console.log(err);
callback(err, new Message(rows[0]));
});
}
I'm getting the follwing 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 'SELECT * FROM e_message WHERE chatid = 1 ORDER BY timestamp DESC LIMIT 0, 1' at line 1]
code: 'ER_PARSE_ERROR',
errno: 1064,
sqlState: '42000',
index: 0 }
The query looks like this via console.log():
INSERT INTO e_message (chatid, message, userid) VALUES(1, 'test123', 1);
SELECT * FROM e_message WHERE chatid = 1 ORDER BY timestamp DESC LIMIT 0, 1;
I don't know whats wrong with this...
EDIT:
If I split it into two queries, I get the result I wanted:
Message.save = function(message, callback){
db.query("INSERT INTO e_message (chatid, message, userid) VALUES(" + message.chatid + ", '" + message.message +"', " + message.userid + ");", function(err, rows, fields){
db.query("SELECT * FROM e_message WHERE userid = " + message.userid + " AND chatid = " + message.chatid + " ORDER BY timestamp DESC LIMIT 0, 1;", function(err, rows, filds){
callback(err, new Message(rows[0]));
});
});
}
Thank you!
node-mysql won't by default allow you to issue multiple SQL statements in a single query.
To allow that, you will need to set the multipleStatements connection option when creating the connection.
Note that allowing this may/will put you at risk of SQL injection, particularly if building the statements as strings. For example, if your message.userid was set to the string 1);drop database production;SELECT (, you'd be in trouble.
In this case what you really want may be to do the insert and a second SELECT LAST_INSERT_ID() to get the id the latest record was inserted with. It will return the latest inserted auto increment key for the session, that is, it will not be affected by other inserts by other connections/sessions.
I have a string that has a query.
The problem is I cannot just append to it, after the where clause there is a group by.
So say i'm given this string:
var query = "select stuff from db where something = 3 group by stuff"
Now I want to append "somethingelse > 5 AND "
Result:
query = "select stuff from db where somethingelse > 5 AND something = 3 group by stuff"
What do I need to do to do this? Thanks
query = query.replace(/where/,'where somethingelse > 5 AND');
David's answer is the most pragmatic if you are passed the query string as-is.
Alternatively, if you're building it up yourself it may be better to allow the list of selectors, query constraints etc. to be passed in so that you create a correct query string initially. Something a bit like:
val query = "select " + selectors.join() +
" from " + tables.join() +
" where " + constraints.join() +
" group by " + groupings.join()