49

I've got an array of strings. When I use .toString() to output it the quotes are not preserved. This makes it hard to build the mysql query using an "in". Consider the following:

SELECT * FROM Table WHERE column IN ('item1','item2','item3','item4')

toString is returning: IN (item1,item2,item3,item4)

There must be a simple fix I am overlooking here.

4
  • 4
    You are preparing a MySQL query in JavaScript? ... mmm ... SQL injection Commented Dec 13, 2011 at 1:19
  • are you using server side javascript? Commented Dec 13, 2011 at 1:29
  • Yes, unless this just a quick prototype, you should be aware that forming SQL on the client is essentially giving anyone complete access to your database. Doesn't matter if it's over HTTPs, the user can just open the debugger and inject away. Commented Dec 13, 2011 at 2:36
  • 1
    Sorry to spoil your fun on sql injection. I have an internal full text search stack that is returning to me indexes of records I need to lookup in mysql. Node_Mysql has a bug which prevents arrays from being properly passed in so I was looking for a work around. I ended up finding a patch that has just not yet found its way to the core: github.com/felixge/node-mysql/issues/126 Commented Dec 13, 2011 at 4:35

7 Answers 7

106

The quotes aren't preserved because they're not actually part of the string value, they're just necessary to indicate string literals in your code.

So, don't use toString(). Instead, one way to do it is as follows:

var arr = ['item1','item2','item3','item4'];

var quotedAndCommaSeparated = "'" + arr.join("','") + "'";

// quotedAndCommaSeparated === "'item1','item2','item3','item4'"

The Array.join() method returns a string that is all of the array elements concatenated into a single string with an (optional) separator between each item. So if you specify a separator that includes the quotation marks and commas you just have to manually append a starting and ending quote for the first and last item (respectively).

(And please tell me you're not using client-side JavaScript to form your SQL.)

EDIT: to allow for an empty array, include a default value for the resulting string, otherwise (as pointed out by missingno) the string would be "''":

var newString = arr.length === 0 ? "" : "'" + arr.join("','") + "'";
// default for empty array here ---^^

(Might be more appropriate to have an if (arr.length===0) to take some other action rather than running the SELECT statement.)

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the suggestion. And no, I'm not building some honeypot for those sql injection rats to come exploit.
What should be the correct behaviour with an empty array? Empty quotes ("''") or empty string? ("")
@missingno - Good point. I'm not sure what would be needed given the result is getting concatenated into an SQL string - might be better not to run the SELECT statement at all. Still, easy to fix - I'll update my answer...
I spent 2 hours and this answer was so close to what I needed lol -- Anyway, I was trying to preserve the quotes from an array, so that I could put everything into CSV format and use commas for some of the text. I got this by using this: csv += '"' + row.join('","') + '"';
This would throw a syntax error if the item contains a quotation (or apostrophe) inside. Make sure to preprocess each item. For example, putting double apostrophe for postgres.
|
18

Use Array.map to wrap each element with quotes:

items.map(function(item) { return "'" + item + "'" }).join(',');

The code gets simpler with ES6 features - arrow functions and template strings (implemented in node.js 4.0 and higher):

items.map(i => `'${i}'`).join(',');

You may also use whitelisting to prevent SQL injections:

const validItems = new Set(['item1', 'item2', 'item3', 'item4']);

items
   .filter(i => validItems.has(i))
   .map(i => `'${i}'`)
   .join(',')

1 Comment

minor improvement: you can call join() without parameters because by default it joins using ,
8
let keys = ['key1','key2']
let keyWithQoutes = keys.map((it) => {return `'${it}'`})
let sql = `SELECT .... FROM ... WHERE id IN (${keyWithQoutes})`
console.log(sql)

output: "SELECT .... FROM ... WHERE id IN ('key1','key2')"

Comments

5

The simple fix is adding the quotes yourself

for(var i=0; i<items.length; i++){
    items[i] = "'" + items[i] + "'";
}

var list_with_quotes = items.join(",");

Do note that I completely ignore SQL injection issues here.

Comments

0

Use JSON.stringify and join them

["hello", "there", 21, 32]
    .map(entry => JSON.stringify(entry))
    .join(",");

returns

"hello","there",21,32

Comments

-1

you can also use string literal and join

var arr = ['item1','item2','item3','item4'];

var quotedAndCommaSeparated = `${arr.join(",")}`;

Comments

-2

Store the quotes:

var names = ["'item1'","'item1'","'item3'"];
alert('IN (' + names[1] + ')'); // IN ('item1')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.