How to know if MySql's conditional INSERT worked? - mysql

With a conditional Insert, I want to know if a row was inserted or if overlap was found.
I have a query that inserts a request into the database if it doesn't overlap with any existing entry. The query works, but how do I know if there's been an collision? The query just executes successfully. Here is my query:
INSERT INTO requests(id, start_time, end_time)
SELECT NULL, 1463631640671,1463636731000,
FROM Dual
WHERE NOT EXISTS (
SELECT * FROM requests
WHERE
start_time < 1463638531000 AND
end_time > 1463636731000
)
For your information. I'm doing this inside Node.js with the mysql package.
and the code looks like this, and it returns 'SUCCESS' every time.
var queryString = "INSERT INTO requests(id, start_time, end_time..."
connection.query(queryString, function(error, results, fields) {
if (!error) {
console.log('SUCCESS!');
}
else {
console.log('Insert into requests unsuccessful.');
console.log('ERROR: ' + error);
}
});

you can inspect results.insertId and see if you have something in it.

Related

Node.js / SQL: Insert only new values

I have a small DB where i insert new data to each column at a different time. Because I'm only inserting one new value, the values for other columns will become NULL. But if thats the case, i want to keep the old value.
My DB looks like this:
One solution would be using coalesce() i guess, but i'm updating each column dynamically, and so the other column names are unknown.
function database_call(request) {
database.query(request, function (err, result) {
if (err) {
console.log(err);
}
});
}
subscribedItem.on("changed", function (dataValue) {
let databaseAttribute = subscribedItem.itemToMonitor.nodeId.value;
let databaseValue = dataValue.value.value;
databaseAttribute = databaseAttribute.substring(databaseAttribute.indexOf('.')+1)
databaseAttribute = databaseAttribute.replace(".", '');
databaseAttribute = databaseAttribute.replace(/"/g, '');
database_call("INSERT INTO Prozessdaten ("+databaseAttribute+") VALUES ("+databaseValue+")");
});
I've found this that implements a 'vertical' coalesce.
You should first do a query like this, using SUBSTRING_INDEX and GROUP_CONCAT to obtain the latest not-null value available in the database for each column.
SELECT
SUBSTRING_INDEX(GROUP_CONCAT(05Hz ORDER BY ID DESC SEPARATOR '##INDEX##'), '##INDEX##', 1) AS 05Hz,
SUBSTRING_INDEX(GROUP_CONCAT(5Hz ORDER BY updated_at DESC SEPARATOR '##INDEX##'), '##INDEX##', 1) AS 5Hz
FROM
table
LIMIT 1
After that, update the single value you really need to update and perform an insert specifying all the values for every column.

validate MySQL select query processed successfully

What i'm trying is validate a select query is processed successfully.
With DB transaction we can validate INSERT , UPDATE, DELETE
like shown below in Codeigniter
$this->db->trans_begin();
//query
if($this->db->trans_status() == false){
return ['error' => 1, 'message' => 'Error massage'];
}
but it does not work with SELECT query.
Is there any other ways to validate this.
Actually my select query will be like this in a scenario
SELECT (amount1+ 10 / 100) FROM test_table
the formula (amount1+ 10 / 100) in the above query will be decoded from the user input. some time a wrong input from user can be like this.
(amount1+ + 10 / 100)
so at the time select query will not execute.
#sintakonte the user input that i mentioned is a formula from a formula builder.
so finally i did a simple trick to validate the query (formula).
do an insertion or update to the table with the select query.
In my scenario once i get the result from the select query i have to update
a column in a table.
$this->db->trans_begin();
$this->db->query("UPDATE table2
JOIN (
SELECT (amount1+ 10 / 100) AS amnt, empID FROM test_table
) AS calculationTB
ON calculationTB.empID = table2.empID AND
SET fnTB.ssoEmployer=calculationTB.amnt");
if($this->db->trans_status() == false){
return ['error' => 1, 'message' => 'Error massage'];
}
$this->db->trans_commit();

update mysql row if timestamp is within last 5 mins

i'm trying to create a stats bot for discord but i am having some issues trying to get part of it to work.
What i am trying to do is record the number of messages sent per channel at 5 min intervals. In my bot i have the following code:
// on message events
bot.on("message", async message => {
if(message.author.bot) return;
if(message.channel.type === "dm") return;
//update channel stats
connection.query(`SELECT * FROM channel_stats WHERE channel_id = '${message.channel.id}' AND date BETWEEN timestamp(DATE_SUB(NOW(), INTERVAL 5 MINUTE)) AND timestamp(NOW())`, (err, rows) => {
if(err) throw err;
let sql;
if(rows.length < 1) {
sql = `INSERT INTO channel_stats (channel_id, date, channel_name, channel_message_count) VALUES ('${message.channel.id}', NOW(), '${message.channel.name}', 1)`;
} else {
let channel_message_count = rows[0].channel_message_count;
sql = `UPDATE channel_stats SET channel_message_count = ${channel_message_count + 1}, channel_name = '${message.channel.name}' WHERE channel_id = '${message.channel.id}'`;
};
connection.query(sql)
});
however, the bot always inserts a new row and never updates an existing one.
I ran the sql query SELECT * FROM channel_stats WHERE channel_id = 'xxxxxxxxxxxxx' AND date BETWEEN timestamp(DATE_SUB(NOW(), INTERVAL 5 MINUTE)) AND timestamp(NOW()) manually via phpmyadmin and this seems to be working correctly - only returns rows created within the last 5 mins.
I'm struggling to understand why the bot is constantly adding new rows. Any help would be appreciated.
Thanks!
managed to resolve this myself, had the channel_id row as int(11) which was causing the channel_id to be truncated.
changed it to VARCHAR(30) and it's working perfectly now.

Inserting data using SET and NOW() with node.js to mySQL Db

Currently this is my code, which inserts the new_item correctly
var new_item = {id_user: id, id_restaurant: id_rest, type: 3, date: date};
connection.query("INSERT INTO table SET ?", [new_item], function(err, results) {
if(err){
...
}
...
}
But now I don't want to send the date with it, I want to use SET ? and do something likedate = NOW() basically I want to insert this:
var new_item = {id_user: id, id_restaurant: id_rest, type: 3};
and use date = NOW()-INTERVAL 6 hour to assign the date.
EDIT: I posted I only wanted Now() but actually I want to set Interval it before inserting.
I think it is better to use moment.js.
You can use Date.now which returns current timestamp(milliseconds), so make sure to format it. The code is as follows:
var a = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss');
Please let me know if this works out
new Date().toISOString().slice(0,10) + " " + new Date().toISOString().slice(11, 19)
same as 'YYYY-MM-DD HH:mm:ss'
Using NOW() is executed by the database interpreter and sets the database time.
You could create a new variable to use in your SQL statement and set the wanted content to that one.
var new_item1 = {id_user: id, id_restaurant: id_rest, type: 3, date: date};
var new_item2 = {id_user: new_item1.id_user, ...};
connection.query("INSERT INTO table SET ?", [new_item2], function(err, results) {
if(err){
...
}
...
}
Then you could configure your column to set the NOW() timestamp as default.

Unable to insert data into mysql in node

Trying to insert data into mysql with 'INSERT INTO users SET ?', I get 500 error in front end. data is reaching the server but unable to insert into database. Tried even 'INSERT INTO users VALUES ?' but still fails. i'm able to retrieve the data from the database('SELECT * FROM users') but not inserting it.
router.post('/userstuff', function(req, res, next) {
var eachuser = {
name: req.body.name,
age: req.body.age
};
connection.query('INSERT INTO users SET ?',eachuser, function(err, rows){
if(err) console.log('Error selecting: %s ', err);
console.log(rows)
});
});
edit: added the schema:
use 02sqldb;
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(30),
age int(2)
);
And what if you try to first do a dummy query. I don't know for sure you can simply put "?" to insert a value without giving a column like
'INSERT INTO table_name (column1,column2,column3,...)
VALUES ('?','?','?',...)'
If it still isn't working you know it's something else.