Getting undefined variables when inserting into mariadb - javascript

I don't know what I'm doing wrong, but I get undefined variables in my query, while the variables are set. I'm trying to create a table and then put some data into it
const obj = {
time: new Date(),
taken: 0,
given: 6.4
}
const pool = mariadb.createPool({
host: 'localhost',
user: 'root',
password: 'root',
database: 'P1data'
})
pool.getConnection().then(async conn => {
let createLive = `create table if not exists live(
time datetime primary key,
taken float not null,
given float not null
)`
conn.query(createLive, (err) => {
if(err) console.error(err.message)
})
const res = await conn.query(`SHOW TABLES`)
console.log(res)
conn.end(err => {
if(err) console.error(err.message)
})
}).catch(err => {
if(err) console.error(err)
})
pool.getConnection().then(conn => {
conn.query(`INSERT INTO live(time, taken, given) VALUES (${obj.time}, ${obj.taken}, ${obj.given});`)
.then(rows => {
console.log(rows);
conn.end();
})
.catch(err => {
console.error(err)
})
}).catch(err => {
if(err) console.error(err)
})
The error I get looks like this:
Error: (conn=354, no: 1054, SQLState: 42S22) Unknown column 'undefined' in 'field list' sql: INSERT INTO live(time, taken, given) VALUES (undefined, 0, undefined); - parameters:[]

INSERT INTO (...) VALUES (...) expects the string values to be enclosed in quotes. And with your current method, also the datetime column probably will be converted from a string on insert, but you don't have any quotes in your query.
Furthermore your obj.time and obj.given seem to be undefined. Thus, your string template for the query evaluates exactly to
INSERT INTO live(time, taken, given) VALUES (undefined, 0, undefined);
So, what the query processor sees in the VALUES is 2 times the identifier undefined (it must be an identifier, because it's not enclosed in quotes) and in the current situation an identifier can only be a column.
You should check your object data
You should not create your queries with string templates, because even if you had the correct quotes, your app is widely open to SQL injections. Use parameterized queries as described in the documentation. Then the mariadb library will care about all necessary quotes and escaping.
conn.query("INSERT INTO live(time, taken, given) values (?, ?, ?)", [obj.time, obj.taken, obj.given])
.then( ...)

Related

Storing JSON objects in the postgreSQL using parameterized query

I am having problems with saving JSON objects in the database using parameterized queries. I am using postman to send this object on red.body
enter image description here
On my server side I havet his code:
queryController.createQuery = (req, res, next) => {
const { info }= req.body;
const sqlQuery = 'INSERT INTO test (info) VALUES ($1) RETURNING *';
db.query(sqlQuery, [info])
.then(result => {
console.log(result);
if (result) res.locals.message = "Saved the query successfully";
next();
})
.catch(err => {
return next({
log: `queryController.createQuery: ERROR: ${typeof err === 'object' ? JSON.stringify(err) : err}`,
message: { err: 'Error occurred in queryController.createQuery. Check server log for more details.'},
})
})
Why is that I still get this error: enter image description here
throw new TypeError('Client was passed a null or undefined query')
^
TypeError: Client was passed a null or undefined query
Here is my table schema:
CREATE TABLE test (
id serial NOT NULL PRIMARY KEY,
info json NOT NULL
);
How do I format $1 correctly to get it accept it as JSON file?
Query example:
EXECUTE 'INSERT INTO test (info) VALUES ($1) RETURNING *' USING '[{"size": "Small", "quantity": 1, "product_id": 1}]'::jsonb;

MongoDB find documents but exclude those without the field

I'm trying to query a collection and sort it by a field that doesnt exist in every record. For example im calling this:
exports.getProductPriceByLosers = (req,res) => {
Market.find()
.sort({ "analytics.one_day_change": 1 })
.select('analytics.one_day_change name')
.limit(10)
.exec((err, data) => {
if (err){
return res.status(400).json({
error: 'No products found'
})
}
res.json(data)
})
}
However the field 'one_day_change' doesn't exist on every record so the result im getting is about 20 products first without that field, and then it returns the prodcuts i do need with the correct sort. Is there a way i can tell mongo not to return those documents i dont need / dont have the data i need?
Thanks!! x
You can use $exists: true to get only documents where that field exists.
exports.getProductPriceByLosers = (req,res) => {
Market.find({"analytics.one_day_change":{ "$exists": true}})
.sort({ "analytics.one_day_change": 1 })
.select('analytics.one_day_change name')
.limit(10)
.exec((err, data) => {
// ...
})
}
Check this example

NodeJs insert current Datetime field into MySQL db

I'm trying to insert a DATETIME field into my MySQL db.
var dt = require('moment')().format('YYYY-MM-DD HH:mm:ss');
pool.query(
`insert into login(id, id_utente, data_login) values(NULL,?,?)`,
[results[0].id],
[dt],
(error, results, fields) => {
}
);
I get this error:
C:\Users\tiger\Desktop\prova\REST_API_WITH_MYSQL-master\node_modules\mysql\lib\protocol\Parser.js:437
throw err; // Rethrow non-MySQL errors
^TypeError: this._callback.apply is not a function
If I try this code, everything comes right:
pool.query(
`insert into login(id, id_utente, data_login) values(NULL,?,"2021-01-27 00:00:00")`,
[results[0].id],
//[dt],
(error, results, fields) => {
}
);
What i'm doing wrong?
You have your parameters in 2 separate arrays. Put your parameters in the same parameter array.
pool.query(
`insert into login(id, id_utente, data_login) values(NULL,?,?)`,
[results[0].id, dt],
(error, results, fields) => {
}
);
The correct format probably is YYYY-MM-DD HH:MM:SS(I think it depends on MySQL configuration, but this is the default) as the docs points out.
So you should try using moment's format() method like this:
const myDate = moment(data.myTime.format('YYYY/MM/DD HH:mm:ss')).format("YYYY-MM-DD HH:mm:ss");
pool.query(
`insert into login(id, id_utente, data_login) values(NULL,?,?)`,
[results[0].id, myDate],
(error, results, fields) => {
}
);

mySql Insert Syntax - Not Inserting What's Expected

I have this INSERT query. It does create a record in the table, but "client" value is 0, and "short" value is null. However, all of the console logs show the correct data. I'm assuming this is a simple syntax error in my use of the question marks. But I can't find that, or seem to get it to work using just variable names either. Any help is appreciated.
app.put("/audit/create", function (req, res) {
console.log("It is getting to the route");
const client = req.body.client;
const short = req.body.short;
console.log(`client: ${client}`);
console.log(`short: ${short}`);
connection.getConnection(function (err, connection) {
connection.query(
`INSERT INTO audits (client, short)
VALUES (?, ?)`,
[
{
client: client,
},
{
short: short,
},
],
function (error, results, fields) {
if (error) throw error;
res.json(results);
console.log(`Audit has been created`);
}
);
connection.release();
});
});
I've also tried using the variables names of ${client}, ${short} in place of the questions marks... and that still gives me the same result. However the console logs that render ${client} and ${short} do log the correct data I'm expecting to see.
Why are you passing objects as the values to the query? Try just:
connection.query(
'INSERT INTO audits (client, short) VALUES (?, ?)',
[ client, short ],
function ...

Send DBNull.Value instead of 'null' in nodeJS MySql

HOw can i send null value to database in node.js?
I am using MySql Package for node JS
and I have some null values to insert which I want to be stored in database as DBNull.Value( as in asp.net) and not as "null" or " ".
Also, I cannot skip any value to insert.
My code below:
var query=connection.query("insert into user_details(user_id,username,screenname,firstname,middlename,lastname,about_me,color_code,Gender,hobbies,occupation,member_of_group,profile_pic,address1,address2,city,pincode,phonenumber,EmailId1,EmailId2,createdate,updatedate) values('"+json.user_id+"','"+ json.username+"','"+json.screenname+"','"+json.firstname+"','"+json.middlename+"','"+json.lastname+"','"+json.about_me+"','"+json.color_code+"','"+json.Gender+"','"+json.hobbies+"','"+json.occupation+"','"+json.member_of_group+"','"+json.profile_pic+"','"+json.address1+"','"+json.address2+"','"+json.city+"',"+json.pincode+",'"+json.phonenumber+"','"+json.EmailId1+"','"+json.EmailId2+"','"+json.createdate+"','"+json.updatedate+"');",function(err,result){
if(!err){
connection.destroy();
callback(result);
}
else
{
console.log(err);
callback('error');
}
});
How can I do that???
First of all, you shouldn't directly concatenate (especially user submitted) values for security reasons and it's just plain tedious when you have a lot of concatenation going on.
Try this instead which makes it easier to work with and properly escapes your values:
connection.query('INSERT INTO user_details SET ?', json, function(err, result) {
connection.destroy();
if (err)
console.log(err);
callback(err, result);
});
or manually specify the values if the keys in the data source do not match up with column names:
var values = {
user_id: json.id,
username: json.user,
// ...
};
connection.query('INSERT INTO user_details SET ?', values, function(err, result) {
connection.destroy();
if (err)
console.log(err);
callback(err, result);
});
Secondly, typically callbacks use "error-first", so passing a real error object as the first argument is better.

Categories

Resources