MYSQL UPDATE TEXT field not working - mysql

I'm trying to update a TEXT field in a MYSQL table. I can't get the UPDATE query to work, even though the original INSERT attempt works fine when the user doesn't exist.
The purpose of the function is to INSERT new row if the user doesn't exist yet, and to UPDATE the textColumn (that always contains a JSON) if the user already exists in the table.
My code:
let first = 'jake';
let last = 'mcdonald';
let first_json = JSON.stringify({a:7, b:7});
let second_json = JSON.stringify({a:'updated'});
const row = {
name: first,
last_name: last,
textColumn: first_json,
}
db.query(`SELECT * FROM tableName
WHERE name="${first}"
AND last_name="${last}"`, (err, result) => {
if (err) console.log(err);
if (result.length < 1) {
db.query(`INSERT INTO tableName SET ?`, row, (err, result) => {
console.log('NEW ROW CREATED: ', result);
})
} else if (result.length > 0) {
console.log('ROW EXISTS');
db.query(`UPDATE tableName
SET textColumn=${second_json}
WHERE name="${first}"
AND last_name="${last}"`, (err, result) => {
console.log('UPDATED: ', result);
}
)
}
}
)
the else if section is what is giving me issues: I reach the inside console.log('ROW EXISTS') but the Update query logs "undefined".
The same UPDATE query works if I try to UPDATE tableName SET name="someNewName" WHERE last_name="original_last_name", but nothing happens when I try to UPDATE the textColumn.

Related

Refer to another field value to affect a new one in MySQL w/Node.js

thanks for reading.
I have a table with 3 fields, one is the ID, which autoincrements and I can´t access it from my Node.js server since it's added by MySql. Another field contains a string, and the last field should be the sum of the 3 first letters of the string field, added to the id.
The thing is, when I do my query I can't just add them up because the id doesn´t exist until the query is sent to the DB.
What should I do? It'd be such an inconvenience to handle the ID autoincrement from the API.
Thanks for your time!
After you insert the row, you can get its ID and update the third column.
connection.query('INSERT INTO yourTable (name) VALUES (?)', [name], function(err, result) {
if (err) {
throw err;
}
let code = name.substr(0, 3) + result.insertId;
connection.query('UPDATE yourTable SET code = ? WHERE id = ?', [code, result.insertId], function(err) {
if (err) {
throw err;
}
});
});
However, this won't work if you're inserting multiple rows in bulk, since result.insertId is just the last row that was inserted.
You could update all the rows where the code
connection.query('INSERT INTO yourTable (name) VALUES ?', names.map(n => [n]), function(err, result) {
if (err) {
throw err;
}
connection.query('UPDATE yourTable SET code = CONCAT(SUBSTR(name, 1, 3), id) WHERE code IS NULL', function(err) {
if (err) {
throw err;
}
});
});

How to get the insrted row data in nodejs-mysql insert query?

i have a simple insert query that looks like that:
let sql = "INSERT into users(name, date) VALUES ('"+name+"', '"+date+"')";
connection.query(sql, (err, result) => {
if(err) {
res.status(500);
} else {
res.send(result) // we have here an object that has only the inserted id
}
});
which i really want is getting the inserted row data not just the id without making another select query to get them.
is there is a way to make that happens in one query?
If you are using:
// include mysql module var mysql = require('mysql');
The mysql module won't return data on the insert's query. It's returning:
Number of rows affected, Number of records affected with the warning, Message
If you wanna get data that you inserted, you should use a query builder or ORM like Sequelize. Sequelize Documentation.
You can get last inserted id using the code below:
SQLconnnection.query(sql, (err, result) => {
if(err) {
console.error(err);
} else {
console.log(result) ;
/*Output=>{affectedRows: 1
changedRows: 0
fieldCount: 0
insertId: 1 =>Last inserted ID Here
message: ""
protocol41: true
serverStatus: 2
warningCount: 0}*/
console.log(result.insertId);//=>last inserted id get
}
});
You can use this to retrieve the
let sql = "INSERT into users(name, date) VALUES ('"+name+"', '"+date+"') ; SELECT * FROM users WHERE id = SCOPE_IDENTITY()";
connection.query(sql, (err, result) => {
if(err) {
res.status(500);
} else {
res.send(result) // we have here an object that has only the inserted id
}
});
SCOPE_IDENTITY() Returns the last identity value inserted

Nodejs Mysql Select Count nested loop insert query

I am new in nodejs and mysql.
I am have an array of objects that i get from post and want to insert it to mysql database.
If the data already exist then run the update query to database.
The problem is Insert query not loop the entire array. it just insert the last entry of Array. Here my code:
Array Data:
bukukasData
[{transactionid: '562018965521',
tanggal: '2018-06-05',
kodeakun: 0, item: 'Saldo',
debit: 100000, credit: 0,
saldo: 100000},
{transactionid:'562018595664',
tanggal:'2018-06-05',
kodeakun: 0,
item: 'Test Data',
debit: 0,
credit: 5000,
saldo:95000}]
NodeJS Query
app.post('/api/addbukukas', function(req, res) {
let bukukasData = req.body.bukukasData;
var status = '';
for (var i = 0; i < bukukasData.length; i++) {
var transactionid = req.body.bukukasData[i].transactionid;
var kodeakun = req.body.bukukasData[i].kodeakun;
var item = req.body.bukukasData[i].item;
var debit = req.body.bukukasData[i].debit;
var credit = req.body.bukukasData[i].credit;
var saldo = req.body.bukukasData[i].saldo;
var tanggal = req.body.bukukasData[i].tanggal;
db.query('SELECT COUNT (*) AS rowCount FROM bukukas WHERE transactionid = ?', [req.body.bukukasData[i].transactionid], function(error, result) {
var rows = result[0].rowCount;
if (rows > 0) {
db.query('UPDATE bukukas SET transactionid=?, kodeakun=?, tanggal=?, item=?, debit=?, credit=?, saldo=? WHERE transactionid = ?', [transactionid, kodeakun, tanggal, item, debit, credit, saldo, transactionid],
function(err, result) {
if (err) {
status = 'Update Gagal';
} else {
status = 'Update Success';
}
})
} else {
db.query('INSERT INTO bukukas (transactionid, kodeakun, tanggal, item, debit, credit, saldo) VALUES (?,?,?,?,?,?,?)', [transactionid, kodeakun, tanggal, item, debit, credit, saldo], function(err, insertresult) {
if (err) {
status = 'Insert Gagal';
} else {
status = "insertresult";
}
})
}
})
}
console.log(status);
return res.json({ status: status });
});
With this code the only data that getting inserted to database just the last data in array. How can i insert all the data in Array to database?
Thanks
Use let instead of var. That will avoid this problem.
The source of this problem is, that in JavaScript the for-loop loops through the variable i and starts bukukasData.length times the db query. The parameter is given as reference. Since the loop iterates very fast, the first sql statement ist started with i set to the last value and all db-statements are executed with i set to bukukasData.length. let was introduced to JavaScript to fix problems like this. With let it will create a copy of the variable in the background.

Bringing separate asynchronous branches back into one branch again

I am working on a node js app which makes use of the express and mysql libraries.
I have a MySQL user table with the following columns:
auto incrementing primary id
username varchar unique
There is no password, etc.
Other tables include:
room
id
room_name
user_room
id
user_id (FK to user table)
room_id (FK to room table)
details
id
user_room_id (FK to user_room table)
col1
col2
col3
Upon trying to connect to a room, I want the database to try pulling their data for that room.
If the data does not exist, I want to see if the username exists in the user table.
If the username does exist, I want to get their id.
If the username does not exist, I want to add their name to the user table and capture the last inserted id
Once having their id, I want to add a record to the user_room table for that user and then several records to the details table based on the newly inserted id in the user_room table.
I seem to be getting into a tangled web going into so many layers.
This is what my code currently looks like:
socket.on('enter room', function(data, callback){
var sql = "select col1, col2, col3 from room JOIN user_room on room.id = user_room.room_id JOIN user on user_room.user_id = user.id JOIN details on user_room.id = details.user_room_id where username = ?";
db_connection.query(sql, [socket.nickname], function (err, result) {
if (err){
console.log("ENTER ROOM DB ERROR: " + err);
return;
}
if (!result.length){
var sql = "select id from user where name = ?";
db_connection.query(sql, [socket.nickname], function (err, result){
if (err){
console.log("ENTER ROOM, SELECT ID DB ERROR: " + err);
return;
}
if (!result.length){
var sql = "insert into user (name) values (?)";
db_connection.query(sql, [socket.nickname], function(err, result){
if (err){
console.log("ENTER ROOM, INSERT ID DB ERROR: " + err);
return;
}
id = result.insertId;
});
}
else {
id = result[0].id;
}
});
//We need to pull things back into one branch again here
//Using the user id and room id I will insert a record into the user_room table
//Then using the newly inserted id in the user_room table, I need to add records to a details table
}
});
//Send col1, col2, and col3 data back to user
//This section here also needs to be pulled back into one branch again
io.sockets.emit('details', result);
});
It mostly works, but because I branch off in two different ways to get the user id (one if it already exists, and one if I need to insert it), I do not know how to pull it back together again into one branch.
What can I do to pull my code back into one branch again so that I can use the id again? Or, is there a better way of approaching this altogether?
A side question: Can I safely remove the "callback" in my opening function, or should I be using this somewhere in my code? I feel that the emit is like a callback to the client so that I do not need "callback" here.
I took a different approach to get userId on upsert. I used promise to send the room data immediately, if available.
socket.on('enter room', function (data, callback) {
let nickName = '';
let roomId = '';
return bookingDetails(nickName).then((details) => {
if (details.length !== 0) {
return Promise.resolve(details);
} else {
return createRoom(nickName, roomId);
}
}).then((details) => {
io.sockets.emit('details', details);
});
});
function createRoom(nickName, roomId) {
return getUserDetails(nickName).then((userId) => {
return insertUserRoom(userId, roomId); //your function
}).then((userRoomDetails) => {
return insertDetails(userRoomDetails); //your function
});
}
function bookingDetails(nickName) {
let sql = "select col1, col2, col3 from room " +
"JOIN user_room on room.id = user_room.room_id " +
"JOIN user on user_room.user_id = user.id " +
"JOIN details on user_room.id = details.user_room_id where username = ?";
return new Promise((resolve, reject) => {
db_connection.query(sql, [nickName], function (err, details) {
if (err) {
return reject("ENTER ROOM DB ERROR: ");
}
return resolve(details);
});
});
}
function getUserDetails(nickName) {
return new Promise((resolve, reject) => {
let sql = "select id from user where name = ?";
db_connection.query(sql, [nickName], function (err, userDetail) {
if (err) {
return reject(err);
}
if (userDetail === null) { //insert
return createUser(nickName);
}
return userDetail;
}).then((userDetail) => {
return resolve(userDetail.id);
});
});
}
function createUser(nickName) {
return new Promise((resolve, reject) => {
let sql = "insert into user (name) values (?)";
db_connection.query(sql, [nickName], function (err, userDetail) {
if (err) {
return reject(err);
}
return resolve(userDetail);
});
});
}

Why affected rows return 0 while update/delete success?

I have statements:
INSERT INTO infotbl(name, phone) VALUES('Alex', '9999999');
and update it:
UPDATE infotbl SET name = 'Alex Johnes', phone = '999 34356063' WHERE id = 1;
then delete:
DELETE FROM infotbl WHERE id = 1;
I've inserted successfully, when I update and delete rows has been change in MySQL. but my code in Node return affected rows = 0. Why?. There is my function to update and delete in Node:
function deleteCustomer (id, callback) {
db.connection.query("DELETE FROM infotbl WHERE id=?", id, (err, result) => {
if (err) throw err;
if (result.affectedRows > 0)
callback(true);
else
callback(false);
});
};
and update function:
function updateCustomer(id, name, phone, callback) {
db.connection.query("UPDATE infotbl SET name = ?, phone = ? WHERE id = ?;", [name, phone, id], (err, result) => {
if (err) throw err;
if (result.affectedRows > 0)
callback(true);
else
callback(false);
});
}
Why node return 0 affected rows when database executed successfully?
The most likely explanation is that there are no rows that satisfy the conditions in the UPDATE and DELETE statements. That is, there are no rows with id value equal to 1.
An UPDATE could affect zero rows if the conditions match one or more rows, but the changes applied to the row result in "no change"... that is, the columns being modified already have the values being assigned.
An UPDATE or DELETE that executes successfully, but affects zero rows, is still considered successful.