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();
});
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);
i need to known the primary key auto_increment value after an insert statement using xdevapi on mysql in nodejs.
my code is:
sqlQueries.getDBConnection(con =>
(function inner(con) {
var query = "INSERT INTO users (name) VALUES ('test')";
var executeSql = con.sql(query).execute();
con.close();
con.done();
return executeSql;
}(con)).then(function (res) {
/***********/
doSomethingWithTheId(id);
/***********/
con.close();
con.done();
}).catch(e => {
cl(e);
})
);
but i don't understand how do i get the id to use it in the doSomethingWIthTheId() function.
I tried to console.log(result) but it seems like i get an array of methods but i don't know how to reach the info i need.
Could you give a try on this:
sqlQueries.getDBConnection(con => {
var query = "INSERT INTO users (name) VALUES ('test')";
var executeSql = con.sql(query).execute();
executeSql.then(function(result) {
let id = result.getAutoIncrementValue();
doSomethingWithTheId(id);
}).catch(function(err) {
con.close();
con.done();
})
});
check this out for more details:
https://dev.mysql.com/doc/dev/connector-nodejs/8.0/module-Result.html
https://dev.mysql.com/doc/dev/connector-nodejs/8.0/module-SqlExecute.html
You can do something like the following:
sqlQueries.getDBConnection(con =>
(function inner(con) {
var query = "INSERT INTO users (name) VALUES ('test')";
var executeSql = con.sql(query).execute();
return executeSql;
}(con)).then(function (res) {
var query = "SELECT LAST_INSERT_ID();";
var id = con.sql(query).execute();
/***********/
doSomethingWithTheId(id);
/***********/
con.close();
con.done();
}).catch(e => {
cl(e);
})
);
See this answer for more details.
I've come across a situation where I need to use a bulk insert with my Node project.
This of course has already been answered here: How do I do a bulk insert in mySQL using node.js
However, I have an express project which I use to create an api. The parameters are turned into an array and I'm having trouble using that array with a bulk insert. Whenever I try to use that route, I get an error of Error: ER_WRONG_VALUE_COUNT_ON_ROW: Column count doesn't match value count at row 1
After some digging I found that it tries to insert:
['foo', 'bar', 'test']
When I need it to insert:
['foo']
['bar']
['test']
Anyways, here's the whole code:
Route
router.post("/", function (req, res, next) {
db.query(
"REPLACE INTO user (`Name`) VALUES (?)",
[req.query.array],
function (error, response) {
if (error) throw error;
console.log(response);
}
)
});
Route Caller
let requestUrl = "http://localhost:3000/user?";
// External api request which returns a list of users
for (let i = 0; i < body.users.length; i++) {
requestUrl += `array=${body.users[i]}&`
}
let addUserRequest = {
url: requestUrl,
method: "POST"
};
request(addUserRequest, function (error, response, body) {
console.log(body);
});
The url that is generated is:
http://localhost:3000/user?array=foo&array=bar&array=test
Try this,
var datatoDB = [];
req.query.array.forEach(function(entry) {
console.log(entry);
datatoDB.push([entry]);
});
Here we are trying to convert this ['foo', 'bar', 'test'] to this [["foo"], ["bar"], ["test"]].
Now, use datatoDB in your function.
router.post("/", function (req, res, next) {
db.query(
"REPLACE INTO user (Name) VALUES ?",
[datatoDB],
function (error, response) {
if (error) throw error;
console.log(response);
}
)
});
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.
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