I have 2 arrays in node js code
names = ['Name1','Name2','Name3','Name4', ...500 more items]
hashes = ['hash1','hash2','hash3','hash4', ...500 more items]
I have 2 columns in database table namely as 'Name' and 'hash'. I want to insert name and hash values in multiple rows simultaneously using only one mysql statement.
I tried to do it with one array. It executed successfully but its not working with 2 arrays. How should i do it ?
The Mysql insert query i wrote for one array is shown below:
var sql = "Insert IGNORE into lu (Name) VALUES ?";
con.query(sql,[array1],function(err, result){
if (err){
con.rollback(function(){
throw err;
});
}
});
You can just map names and hashes into one array - [["Name1", "hash1"], ...], then insert a nested array of elements.
var sql = "INSERT IGNORE INTO lu(Name, hash) VALUES ?";
var names = ['Name1','Name2','Name3','Name4'];
var hashes = ['hash1','hash2','hash3','hash4'];
var toOneArray = function(names, hashes) {
return names.map(function(name, i) {
return [name, hashes[i]]
});
}
con.query(sql, [toOneArray(names, hashes)], function(err, result) {
if (err) {
con.rollback(function(){
throw err;
});
}
});
I do not know if there is another way.
Related
I need to make 2 requests to my API to insert data in 2 different table:
Workflow:
request to get the last id + 1 => create the array I need (last_id, values) => two INSERT in MySql, 1st with varius data, 2nd with the array I created.
router.post("/addentry", function (req, res) {
let sql = "SELECT MAX(id) + 1 AS last_id FROM entries;"; // I get the id
let query = connection
.query(sql, (err, results) => {
if (err) throw err;
res.header("Access-Control-Allow-Origin", "*");
// put the id in a variable
var last_id = results[0].last_id;
var categoriesMap = req.body.categories;
var valCat = Object.values(categoriesMap);
// I create the array with other data
var catArray = valCat.map((item) => {
return [last_id, item];
});
})
.then((catArray) => {
let sql = `BEGIN; INSERT INTO entries (title,kindof) VALUES("${[
req.body.title,
]}","${req.body.kindof}");
INSERT INTO categories_main (entry_id, cat_id) VALUES ? ;
COMMIT;`;
let query = connection.query(sql, [catArray], (err, results) => {
if (err) throw err;
console.log(results);
res.header("Access-Control-Allow-Origin", "*");
res.send("Entry added to DB");
});
});
The first part works perfectly but with the second I get
TypeError: connection.query(...).then is not a function
Any idea how to do it?
Thanks
First things first, you should make sure that you use node-mysql2 instead of node-mysql. node-mysql2 has a built in functionality that helps making multiple queries inside a single connection. I have provided you this answer that exemplifies how to use it properly.
Moving forward, after you've done that, to be able to work with your result object, you will need JSON.
The following syntax is what you probably want to use:
var stringify = JSON.parse(JSON.stringify(results[0]));
for (var i = 0; i < stringify.length; i++) {
var last_id = stringify[i]["last_id"];
}
I need to make 2 requests to my API to insert data in 2 different table:
From code, I see that you are intending to do a single API call to the server and run 2 queries.
You can do .then only on a Promise, so as we can see connection.query is not returning a Promise and hence not then able.
Also you are setting response headers multiple times res.header("Access-Control-Allow-Origin", "*"); do this only once in a request cycle. So lets follow the callback approach instead of then.
let sql = "SELECT MAX(id) + 1 AS last_id FROM entries;"; // I get the id
let query = connection
.query(sql, (err, results) => {
if (err) {
res.header("Access-Control-Allow-Origin", "*");
return res.status(500).send({error:'server error'});
}
// put the id in a variable
var last_id = results[0].last_id;
var categoriesMap = req.body.categories;
var valCat = Object.values(categoriesMap);
// I create the array with other data
var catArray = valCat.map((item) => {
return [last_id, item];
});
let sql = `BEGIN; INSERT INTO entries (title,kindof) VALUES("${[
req.body.title,
]}","${req.body.kindof}");
INSERT INTO categories_main (entry_id, cat_id) VALUES ? ;
COMMIT;`;
let query = connection.query(sql, [catArray], (err, results) => {
if (err) {
res.header("Access-Control-Allow-Origin", "*");
return res.status(500).send({error:'server error'});
}
console.log(results);
res.header("Access-Control-Allow-Origin", "*");
res.send("Entry added to DB");
});
})
Here the complete solution, starting from what #SubinSebastian advised to me.
First of all I needed node-mysql2, that alows promises and therefore chained requests.
And then:
router.post("/addentry", function (req, res) {
let sql = "SELECT MAX(id) + 1 AS last_id FROM entries;";
connection.promise().query(sql)
.then((results) => {
// I get the value from results
var stringify = JSON.parse(JSON.stringify(results[0]));
for (var i = 0; i < stringify.length; i++) {
console.log(stringify[i]["last_id"]);
var last_id = stringify[i]["last_id"];
}
// I get some parameters and I create the array
var categoriesMap = req.body.categories;
var valCat = Object.values(categoriesMap);
var catArray = valCat.map((item) => {
return [last_id, item];
});
let sql = `BEGIN; INSERT INTO entries (title,kindof) VALUES("${[
req.body.title,
]}","${req.body.kindof}");
INSERT INTO categories_main (entry_id, cat_id) VALUES ? ;
COMMIT;`;
// array as second query parameter
let query = connection.query(sql, [catArray], (err,results) => {
if (err) throw err;
});
})
.catch(console.log);
How can I insert an array to a table in MySQL with nodejs? The code below works if the array is just one, but if there is more items in the array, I get the error: "ER_WRONG_VALUE_COUNT_ON_ROW"
I need to insert all the array values in the table. How can I achieve this?
Here is what I got so far:
let workoutArray = [];
result.forEach(function(name) {
workoutArray.push(name.exercise);
});
let sql2 = 'INSERT INTO reps (email, date, workout, exercise) VALUES (?,?,?,?)';
connection.query(sql2, [user, addDate, workoutToIndex, workoutArray], function (error2, result2) {
if (error2) throw error2;
console.log(result2);
});
response.end();
});
Instead of sending an array as a parameter, try sending an array from an array.
Example:
let workoutArray = [];
result.forEach(function(name) {
workoutArray.push(name.exercise);
});
let sql2 = 'INSERT INTO reps (email, date, workout, exercise) VALUES (?,?,?,?)';
connection.query(sql2, [[user, addDate, workoutToIndex, workoutArray]], function (error2, result2) {
if (error2) throw error2;
console.log(result2);
});
response.end();
});
I am using nodejs and the mysql npm package and I'm trying to select from a table where other_text =
Here is what it looks like:
var query = connection.query(`SELECT id FROM ${tableName} WHERE other_text = ?`,
attributeName.other_text, function (err, rows) {
...
I have read that using ? will automatically escape the user entered string. In most of the examples that I see that do this, they have brackets around the 2nd parameter in the query function, like below:
var query = connection.query(`SELECT id FROM ${tableName} WHERE other_text = ?`,
[attributeName.other_text], function (err, rows) {
...
Are the brackets necessary in order to escape the string that's passed in? It works when I try it, but I don't even know how to test a SQL injection so I don't really know if the brackets are necessary or even correct.
Thank you.
The brackets represent an array. You can use an array in case you have more values you want to use with your query.
For example, let's say that you want to select multiple columns from the table, and you want to pass them to the statement, you would use something like this:
connection.query(`SELECT ?? FROM ${tableName}`,
[col1, col2, col3], function (err, rows) {
It also does work in combination with strings, numbers or even objects. Let's say that you want to update the user with id 1 from Users table table. You would do something like this:
const tableName = 'users';
const whereCondition = {id: 1};
const whaToUpdate = {name: 'newName'}
const mysql = require('mysql');
const statement = mysql.format('update ?? set ? where ?', [tableName, whaToUpdate , whereCondition]);
I also recommend using .format for better code reading.
Finally you would have something like this:
connection.query(statement, (error, result, fields) => { });
The bracket uses for passing multiple values. You can use escape function or question mark (?) placeholder to prevent SQL injections. Lets have a look in details:
We are using mysql node module to provide all example below (Example 1 to Example 5). The below code is necessary to follow those example.
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
MySQL con.query has overloaded function.
Example 1: it takes sql string and callback function
var sql = 'SELECT * FROM customers;
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
});
Example 2: it takes sql string, parameter and callback function
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ?';
con.query(sql, [adr], function (err, result) {
if (err) throw err;
console.log(result);
});
In Example 2, the second parameter uses [ ] so that you can pass
array to provide multiple values as parameter. Example 3 shows how to pass multiple values in second parameter.
Example 3: Here two values are passed name and address into [ ]
var name = 'Amy';
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE name = ? OR address = ?';
con.query(sql, [name, adr], function (err, result) {
if (err) throw err;
console.log(result);
});
Preventing SQL injections
To prevent SQL injections, you should use escape function the values when query values are variables provided by the user.
Example 4: Here we used escape function to avoid SQL injections
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ' + mysql.escape(adr);
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
});
Example 5: Escape query values by using the placeholder ? method
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ?';
con.query(sql, [adr], function (err, result) {
if (err) throw err;
console.log(result);
});
More details
if I have a query like the following:
var queryString = "INSERT INTO pid SET title = '" + randomTitle + "', poc = '" + random + "';"
connection.query(queryString, function(err, rows, fields) {
...(do something here)
});
, is there a way I can retrieve information for the just-inserted row without performing a new query (in my particular case, I want the auto-generated primary key value).
For instance, can I use the construct with the "query" object (below) and then perhaps use one of the query.on callback to retrieve the information about the just-inserted row?:
var query = connection.query(queryString, function(err, rows, fields) {
query.on('fields', function(fields) {
... get the field information?
});
query.on('result', function(row) {
.. get the field information?
});
});
If not via the query callbacks, is there another way? Thanks for any response!
According to docs it is possilbe. Notice that callback function of insert query does not have rows and fields but only result parameter:
connection.query(queryString, function(err, result) {
if (err) {
// handle error
}
console.log(result.insertId); // prints inserted id
}
Your query is also vulnerable to sql injection. It should look like this:
var queryString = "INSERT INTO pid SET title = ?, poc = ?";
connection.query(queryString, [randomTitle, random], function(err, result) {
// ...
}
I want to insert multiple rows into mysql thru node.js mysql module. The data I have is
var data = [{'test':'test1'},{'test':'test2'}];
I am using pool
pool.getConnection(function(err, connection) {
connection.query('INSERT INTO '+TABLE+' SET ?', data, function(err, result) {
if (err) throw err;
else {
console.log('successfully added to DB');
connection.release();
}
});
});
}
which fails.
Is there a way for me to have a bulk insertion and call a function when all insertion finishes?
Regards
Hammer
After coming back to this issue multiple times, I think i've found the cleanest way to work around this.
You can split the data Array of objects into a set of keys insert_columns and an array of arrays insert_data containing the object values.
const data = [
{test: 'test1', value: 12},
{test: 'test2', value: 49}
]
const insert_columns = Object.keys(data[0]);
// returns array ['test', 'value']
const insert_data = data.reduce((a, i) => [...a, Object.values(i)], []);
// returns array [['test1', 12], ['test2', 49]]
_db.query('INSERT INTO table (??) VALUES ?', [insert_columns, insert_data], (error, data) => {
// runs query "INSERT INTO table (`test`, `value`) VALUES ('test1', 12), ('test2', 49)"
// insert complete
})
I hope this helps anyone coming across this issues, I'll probably be googling this again in a few months to find my own answer 🤣
You can try this approach as well
lets say that mytable includes the following columns: name, email
var inserts = [];
inserts.push(['name1', 'email1']);
inserts.push(['name2', 'email2']);
conn.query({
sql: 'INSERT into mytable (name, email) VALUES ?',
values: [inserts]
});
This should work
You can insert multiple rows into mysql using nested arrays. You can see the answer from this post: How do I do a bulk insert in mySQL using node.js