Update table with myCon.query using an array of set values - mysql

I am trying to use an array of values to populate an escaped sql query. The array being accepted.
I was using:
function genUpdateString(settings) {
var sql = "";
var first = true;
for (attr in settings) {
if (
settings[attr] != undefined &&
attr != "userid" &&
attr != "api_key"
) {
if (first) {
first = false;
} else {
sql += ", ";
}
sql += attr + "='" + settings[attr] + "'";
}
}
return sql;
}
sql_update = genUpdateString(...);
var sql = "UPDATE user SET " + sql_update + " WHERE name = '" + newSettings.userid + "'";
myCon.query(sql, (err, result) => {
This works fine but when I tried to move to the escaped format it crashes:
var sql = "UPDATE user SET ? WHERE name = ?";
myCon.query(sql, [sql_update, userid], (err, result) => {
When I create the string manually it runs through fine and updates my database tables but using the second method it crashes with the 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 ''age=\'33\'' WHERE name = 'Josephy Krakowski'' at line 1

Your genUpdateString function isn't SQL injection safe either – just adding single quotes isn't secure.
Something like this is – we're generating the query fragment with question marks and the args "in parallel".
function genUpdateAndArgs(map) {
const names = [];
const args = [];
for(var key in map) {
const value = map[key];
if(value !== undefined) {
names.push(key);
args.push(value);
}
}
// ['foo', 'bar'] => 'foo = ?, bar = ?'
const namesFragment = names.map((name) => `${name} = ?`).join(', ');
return [namesFragment, args];
}
const settings = {
'foo': 123,
'bar': 456,
};
const userId = 1337;
const [namesFragment, updateArgs] = genUpdateAndArgs(settings);
const query = `UPDATE user SET ${namesFragment} WHERE name = ?`;
const args = [].concat(updateArgs).concat(userId);
console.log(query, args);
The output is
UPDATE user SET foo = ?, bar = ? WHERE name = ?
[ 123, 456, 1337 ]
which you could then plug into db.query...
However I really heartily recommend a query builder like Knex instead – in Knex, the same would be approximately
knex('user')
.where('name', userId)
.update(settings)

Related

Node function inputting undefined variables into SQL database

I'm sure this is a simple error in my syntax but I'm currently using a nodejs function to input into my SQL database, however, while the overall query works, and some variables get input correctly, a couple are input as undefined, which has thrown me for a loop. I'll input the query below and I presume I either added extra punctuation where not required or something.
con.query("INSERT INTO _rounds(roundnum, roundse, roundtk, winner) VALUES('"+ roundnumres +"', '"+ roundse +"', '"+ roundtk +"', '"+ roundwinner +"')", function (err, result) {
});
For more information, the roundnumres and the roundtk variables are the ones inserted as undefined, and are both defined by a random string generator which looks as follows:
function makese(length) {
var roundse = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var d = 0; d < length; d++ ) {
roundse += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return roundse;
}
var roundse = makese(20);
Any help would be appreciated!
you could do this. you don't have to concat strings using plus
const query = `INSERT INTO _rounds(roundnum, roundse, roundtk, winner) VALUES('${roundnumres}', '${roundse}, '${roundtk}', '${roundwinner}')"
con.query(query, () => {})

Npm mysql - can't I query WHERE conditions using a single object?

I am using express and npm mysql (Link)
I want to do a call using
query('SELECT * FROM TABLE WHERE ?', where, cb)
where is a javascript object f.e. : {col1: 'one', col2: 'two'}
But it seems that this doesn't work. It works for SET though to update multiple columns at once.
I want a general method where I can send a different combination of columns to search. I was wondering if there is a built in method to do this.
Meanwhile, I created this script:
var andQuery = "";
var andParams = [];
var isFirst = true;
for (var filter in where) {
if (where.hasOwnProperty(filter)) {
if(!isFirst) {
andQuery += " AND ? ";
} else {
andQuery += " ? ";
isFirst = false;
}
andParams.push({[filter]: where[filter]});
}
}
db.query(
'SELECT * FROM `Table` WHERE ' + andQuery, andParams, (err, results) => {

Fatal error: Can't use function return value in write context in cakephp 3

getting this error in my local server. but this code is running in online
where its not showing any error. now what can i do? error show empty(count($leadcount)) this condition
if(empty(count($leadcount))){
if(!empty($leadManagements)){
$LeadSend = $this->LeadSend->newEntity();
$inqData['requirement_id'] = $Requirements->id;
$inqData['lead_management_id'] = $leadManagements->id;
$inqData['send_date'] = Time::createFromFormat('Y-m-d', date('Y-m-d'));
$inqData['lead_type'] = 'booking';
$inqData['is_active'] = 1;
$inqData['is_delete'] = 1;
$LeadSend = $this->LeadSend->patchEntity($LeadSend, $inqData);
if($this->LeadSend->save($LeadSend)){
$expression = new QueryExpression('booking_lead_count = booking_lead_count + 1');
$expression2 = new QueryExpression('lead_sent_count = lead_sent_count + 1');
$this->LeadManagements->updateAll([$expression,$expression2], ['id' => $leadManagements->id]);
//lead_type send_date
$this->notificationBuyer($this->request->data);
$this->notificationSeller($this->request->data);
}
}
} else {
/// allready send inquery
}
Surely it should simply be either if(empty($leadcount)) or if(count($leadcount) == 0).

Unable to get value from JSON after mySQL

var sender_username = req.session.user_id;
var recipient_username = req.body.recipient_username;
var content = req.body.content;
var sql = ' SELECT sender_username, recipient_username, COUNT(recipient_username) as count FROM message WHERE sender_username = "'+sender_username+'" AND recipient_username = "'+recipient_username+'" GROUP BY sender_username LIMIT 1 ';
var message_no = 0;
var data;
connection.query(sql, function(err, result) {
if (err) {
res.send(err);
}
else {
data = result;
// res.send(data); < - this works
// res.send(result); <- this works
// res.send(result.count); <- undefined
}
});
res.send(data); // undefined (can't seem to save to variable after connection.query())
The res.send(result); seems to work. It gives:
[{"sender_username":"sender","recipient_username":"recipient","count":2}]
I am just trying to get the value for count and save that to a variable, but things like result.count are returning undefined for some reason.
It's because the JSON is an array, so you should access it like the following
res.send(result[0].count);

Fastest way to get JSON object into mysql using node

Using a prior example? How could I insert/update a mysql table using
a JSON object without manually naming the table column headers? And insure it async.
var mysql = require('node-mysql');
var conn = mysql.createConnection({
...
});
var values = [
{name:'demian', email: 'demian#gmail.com', ID: 1},
{name:'john' , email: 'john#gmail.com' , ID: 2},
{name:'mark' , email: 'mark#gmail.com' , ID: 3},
{name:'pete ' , email: 'pete#gmail.com' , ID: 4}
];
// var sql = "INSERT INTO Test (name, email, n) VALUES ?";
conn.query(sql, [values], function(err) {
if (err) throw err;
conn.end();
})
You could do something like this:
for(var i = 0; i < values.length; i++){
var post = values[i]
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
// Finish
});
}
EDIT
This is how you inserts multiple 'posts' at once.
INSERT INTO posts (type, details)
VALUES
('Helen', 24),
('Katrina', 21),
You would have to loop through the first value to get the names like this.
var names = [];
for(name in values[0]){
names.push(name);
// That would give you name, email, id
}
Then you would have to create your own string to insert.
var newvalues = [];
for(var i = 0; i < values.length; i++){
newvalues.push('(' + values[i].join(',') + ')');
}
Then to execute the query:
connection.query('INSERT INTO posts (' + names.join(',') + ') VALUES ' + newvalues.join(',') , function(err, rows, fields) {
// Result
});
You would have to test the code yourself, this is just how you would do it.
Look at the 'Custom Format' part here. If you notice, this example using named placeholders in the query, allowing you to pass an object, and the placeholders are replaced with the matching attributes from the object. I've also pasted the relevant section for clarity:
connection.config.queryFormat = function (query, values) {
if (!values) return query;
return query.replace(/\:(\w+)/g, function (txt, key) {
if (values.hasOwnProperty(key)) {
return this.escape(values[key]);
}
return txt;
}.bind(this));
};
connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
You could create a small function that maps an array with that format to an insert statement.
You can easily loop through the fields and use some string concatenation.
Better option is (using MySQL Connection):
app.get('/yourcontroller/:id', function (req, res) {
var id = req.params.id;
var dataUpdate = req.body;
connection.query(
'UPDATE yourtable SET ? Where ID = ?',
[dataUpdate, id],
function (err, result) {
if (err) throw err;
console.log('Updated data ! Changed ' + result.changedRows + ' rows');
}
);
});