0

I'm getting an error on the line that says

const INSERT_PRODUCTS_QUERY = 'INSERT INTO products(name, price) VALUES('${name}',${price})';

I know the error emanates from the single quotes in '${name}' but I also tried removing the single quotes in an attempt to get rid of this error and still get an error that says:

{
"code": "ER_PARSE_ERROR",
"errno": 1064,
"sqlMessage": "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 '{name}, ${price})' at line 1",
"sqlState": "42000",
"index": 0,
"sql": "INSERT INTO products(name, price) VALUES(${name}, ${price})"
}

Here's my code:

const express = require('express');
const cors = require('cors');
const mysql = require('mysql');

const app = express();

const SELECT_ALL_PRODUCTS_QUERY = 'SELECT * FROM products';

const connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'react_sql'
});

connection.connect(err => {
    if(err) {
        return err;
    }
});

app.use(cors());

app.get('/', (req, res) => {
    res.send('go to /products to see products')
});

app.get('/products/add', (req, res) => {
    const { name, price } = req.query;
    const INSERT_PRODUCTS_QUERY = 'INSERT INTO products(name, price) VALUES('${name}',${price})';

    connection.query(INSERT_PRODUCTS_QUERY, (err, results) => {
       if(err) {
           return res.send(err);
       } else {
           return res.send('successfully added products');
       }
    });

})

app.get('/products', (req, res) => {
    connection.query(SELECT_ALL_PRODUCTS_QUERY, (err, results) => {
        if(err) {
            return res.send(err)
        } else {
            return res.json({
                data: results
            })
        }
    });
});

app.listen(4000, () => {
    console.log("listening port 4000");
});
devserkan
  • 16,870
  • 4
  • 31
  • 47
sp92
  • 873
  • 1
  • 6
  • 17
  • 2
    Learn to use parameters and you won't ever have these problems. – Gordon Linoff Aug 17 '18 at 12:32
  • @GordonLinoff you mean get rid of the $ and {} for name and price? I tried that but it doesn't work. – sp92 Aug 17 '18 at 12:34
  • You can use : const INSERT_PRODUCTS_QUERY = 'INSERT INTO products(name, price) VALUES(:name,:price)'; – Hemadri Dasari Aug 17 '18 at 12:36
  • No, he means use parameters, replace with `?`, and then pass the parameters as the second argument to your query. https://www.npmjs.com/package/mysql#escaping-query-values – Keith Aug 17 '18 at 12:37
  • Sql strings in javascript are very hack-able. If someone modified the variable then they would be able to inject any query in to the database. Even if it is const someone could send a hack query to the service. This is not secure code. – Stephen Flynn Aug 17 '18 at 12:38
  • Also if you can, try with string literals. – joseatchang Aug 17 '18 at 12:41
  • Have a look at this question and answer and stop using concatenated unescaped strings in your SQL. https://stackoverflow.com/questions/41168942/how-to-input-a-nodejs-variable-into-an-sql-query – ChatterOne Aug 17 '18 at 12:51

4 Answers4

1

I don't know so much about SQL and its queries, so for this subject (strings, security, etc) listen to other people.

As you can see in the comments this opens the code to SQL Injections, better avoid to using it.

Thanks, @Keith.


But if you want to use variables in your strings either you need to combine different string pieces or you should use template literals.

PS: If you still really, really want to use template literals, you can check this node package which is sql-template-strings for NodeJS.

Notice the backticks: ``

const name = "foo";
const price = 100;

const INSERT_PRODUCTS_QUERY = `INSERT INTO products(name, price) VALUES('${name}',${price})`;

console.log( INSERT_PRODUCTS_QUERY );
devserkan
  • 16,870
  • 4
  • 31
  • 47
  • Thanks, @Keith. I've updated my answer. Actually, React escapes string variables automatically in the view if I remember right but this question is related with Node.js, not React itself. So, the risk is out there right? – devserkan Aug 17 '18 at 12:49
  • Ah the backticks!! that's why I was missing! Thank you! – sp92 Aug 17 '18 at 12:53
  • `So, the risk is out there right?` Yes, the escaping in React is also a different type of escaping, it's not SQL escaping but HTML escaping. And even if it was SQL escaping you couldn't use it Client side as it could of course be hacked. – Keith Aug 17 '18 at 12:55
  • 1
    @Keith, I'm not a SQL guy also a learner for React, Node.JS. Thanks. What do you think about this package? https://www.npmjs.com/package/sql-template-strings Maybe a workaround? – devserkan Aug 17 '18 at 12:56
  • @Keith yea I understand it's not secure. I'm just doing this for the sake of learning. I'll get to the gritty stuff later, just trying to take it 1 step at a time. – sp92 Aug 17 '18 at 12:57
  • Yes, `sql-template-string` looks like a good option, it internally will be using sql parameters so that's good.. :) – Keith Aug 17 '18 at 13:04
  • Thanks again @Keith, I've added this info into my question. But I think still it is better to avoid using this if there is a safer way. – devserkan Aug 17 '18 at 13:08
1

SQL parameters in MySQL are not only a convenient way of passing parameters to query's, there also a must if you don't want to open your site to SQL Injection problems.

The changes you need to make are very minimal..

First change your query to ->

const INSERT_PRODUCTS_QUERY = 
   'INSERT INTO products(name, price) VALUES(?, ?)'

And when you use this query pass the parameters as the second parameter.

connection.query(SELECT_ALL_PRODUCTS_QUERY, 
  [name, price],
  (err, results) => {
Keith
  • 22,005
  • 2
  • 27
  • 44
  • 1
    Upvoted, and probably this must be the accepted answer for the SQL context. Other answers (including mine) are about concatenating the strings with variables in JS. – devserkan Aug 17 '18 at 12:59
0

Template literals are not surrounded by simple quotes but by back-ticks "`"

It should become :

const INSERT_PRODUCTS_QUERY =  `INSERT INTO products(name, price) VALUES('${name}',${price})`
C.Champagne
  • 5,381
  • 2
  • 23
  • 35
  • 1
    Please be advised, this opens the user to SQL Injection,.. Best avoided. – Keith Aug 17 '18 at 12:43
  • @Keith thanks, you are right. It creates the same issues than string concatenation. I will delete my answer unless can update it with information that other answers don't provide. – C.Champagne Aug 17 '18 at 13:26
0

You are not providing literals correctly, modify your query as following, this is PHP representation you can change accordingly.

INSERT INTO products(name, price) VALUES('".${name}."','".${price}."');

Single quote for literal value is ambiguous with language single quote, which breaks query syntax.

This is not best way to achieve this, as it opens your query to SQL Injection.