Grouping SQL results by month - javascript

I am trying to write a function that reads from an mssql database. Calculates the average number of days taken by engineering on a project and the percentage of on time projects and stores the results in my own Mongo database. Below is what I have, which works
async function update(m, y) {
var query = "SELECT AVG(DATEDIFF(day, DateBlockReleased, DateEngineeringTargetComplete)) AS AvgDays, SUM(IIF(DATEDIFF(day, DateBlockReleased, DateEngineeringTargetComplete)>=0, 1, 0)) AS OnTime, COUNT(DateBlockReleased) AS Total FROM JobData.JobData, JobData.BOMInfo, JobData.DesignInfo WHERE JobData.JobData.BOMInfoID = JobData.BOMInfo.BOMInfoID AND JobData.JobData.DesignInfoID = JobData.DesignInfo.DesignInfoID AND JobData.DesignInfo.DateEngineeringTargetComplete IS NOT NULL AND JobData.JobData.isArchivedDate IS NOT NULL AND MONTH(JobData.JobData.isArchivedDate) =" + m + " AND YEAR(JobData.JobData.isArchivedDate) =" + y;
sql.connect(config, (err) => {
if (err) {
console.log("Error while connecting to database :- " + err);
} else {
var request = new sql.Request();
request.query(query, function (err, rs) {
if (err) {
console.log("Error while querying database :- " + err);
sql.close();
} else {
var record = {
_id: m + "_" + y,
AvgDays: rs.recordset[0].AvgDays,
OnTime: rs.recordset[0].OnTime / rs.recordset[0].Total * 100
};
kpiConn.collection('engineeringData').insertOne(record);
sql.close();
}
})
}
})
}
However when I run this for multiple months and years I get the records for the first 10 months and then abort errors from the SQL server. I believe this is because I am querying the database too many times at once and so I am trying to condense this into one SQL query but am struggling to group the results by month. I don't know whether it's easier to return the entire database with ontime calculated and then use javascript to group them? Also open to any suggestions to make my query in general more streamlined as I'm quite new to SQL (Have a feeling I should be using joins)

Try doing a select all with a sort.
If you have a column in your database with months etc and then also time taken you can run something like this.
SELECT column-list
FROM table_name
[WHERE condition]
[ORDER BY column1, column2, .. columnN] [ASC | DESC];
For you would just be ;
select * FROM table_name
Hope this helps :)

Related

MySQL In NodeJS is grabbing IDs from a database but it's changing the last 2 digits of it to 00

I'm having troubles with MySQL for node, when I see the IDs on the DB, they look fine, but when I grab it with the MySQL (code below) the last 2 digits are replaced by 0, any ideas on what's happening & how to solve it? I also will attach a picture of the database data & settings
dbPool.getConnection((err, con) => {
if (err) throw err
con.query(`SELECT * FROM node_1 WHERE gid`, (err, rows:guildData[]) => {
if(err) throw err
rows.forEach(row => {
client.dataGuilds.set(`${row.gid}`, row)
console.log(row.gid)
})
})
con.release()
})
The problem is that DB bigint exceeds Number.MAX_SAFE_INTEGER. You can use BitInt(x) to convert:
const x = BigInt(928711151708167415);
console.log(x);
Solved, instead of turning a bigint into a string, just store it as an string

Error: ER_PARSE_ERROR: You have an error in your SQL syntax;

I'm trying to insert values using mysql in nodejs. I had written the following code and installed MySQL support via npm,But canot to INSERT INTO the table due to this problem.
My code;
var mysql = require('mysql');
var values=randomValueHex(8);
var sql = "INSERT INTO `activationkeys`(`activationKey`, `productId`)
VALUES ( values ,'3')";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("1 record inserted");
});
My Error on terminal:
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 ''3')'
How can i solve this problem?
Why are you using back quote for the column names? We do not need that in column names. You can simply create your dynamic sql query by using + operator on the column values like this:
var sql = "INSERT INTO activationkeys (activationKey, productId) VALUES ( " + values + " ,'3')";
Instead of
var sql = "INSERT INTO `activationkeys`(`activationKey`, `productId`)
VALUES ( values ,'3')";
Please try this
var sql = "INSERT INTO `activationkeys`(`activationKey`, `productId`)
VALUES ( " + values + " ,'3')";
provided values is a string
values currently means nothing the way you're using it in the SQL query.
What is values? Is it an integer, or a string?
Nevertheless, you need to concatenate the values variable within the string.
var sql = "INSERT INTO `activationkeys`(`activationKey`, `productId`) VALUES (" + values + ",'3')";
And one more correction values variable have to give like this '" + values + "' . This is the most correct way of define as a variables. Otherwise you give like this " + values + " , you may be have an error accure like this Error: ER_BAD_FIELD_ERROR: Unknown column 'xxxxxx' in 'field list'. And my code is
var sql = "INSERT INTO `activationkeys`(`activationKey`, `productId`) VALUES ( '" + values + "' , 3 )";
This is simple way to write SQL query in you JavaScript code.
Try It Once
const QUERY = INSERT INTO users (firstName, lastName) VALUES ( "${firstName}", "${lastName}")
Note: Please wrap your complete query into the back ticks.

Javascript SQLite for Cordova app - search using parameters where a string contains a substring case-insenstive

In my Cordova app, I need to query a SQLite database and select rows where the value of the column EventName contains a substring. I want to be able to use ? to hold values to avoid SQL injection. I tried this query:
SELECT * FROM EventName WHERE 1 = 1 AND lower(EventName) LIKE lower('%?%');
This is my JavaScript code that I use to query the database:
function searchEvent(onSearch, eventName) {
// First create the query string
var params = [];
var query = "SELECT * FROM Event WHERE 1 = 1";
if (eventName != null && eventName != "") {
query += " AND lower(EventName) LIKE lower('%?%')";
params.push(eventName);
}
query += ";";
console.log(query); // Log the query
console.log(params); // Log the parameters
// Then execute query statement
db.transaction(function(tx) {
tx.executeSql(query, params, function(tx, rs) {
onSearch(rs);
});
}, function(err) {
console.log(err); // This statement was executed
});
}
This is the logged query:
SELECT * FROM Event WHERE 1 = 1 AND lower(EventName) LIKE
lower('%?%');
This is the logged paramaters:
[ 'myInput' ]
This is the error the was returned:
{
code: 5,
messsage: 'number of \'?\'s in statement string does not match argument count'
}
As you can see there is 1 ? placeholder and 1 input parameter so the numbers DO match. I think it is because the ? is between the single quotes ('') so it is thought to be a part of the searched string. How do I fix this?
EDIT:
The JavaScript statement "SELECT * FROM Event WHERE 1 = 1" + " AND lower(EventName) LIKE lower('%" + eventName + "%')" is ok, but I wanna use a method that can protect me against SQL injection
In order to prevent the eventName from SQL injection, check it with regEx validation to include only alphanumneric and whitelist specific special characters /^[ A-Za-z0-9_#./#&+-]*$/. Also try this regEx /^[a-zA-Z0-9!##\$%\^\&*)(+=._-]+$/g. I do not believe that ? would work with SQL SELECT statement, so you need to pass +eventname+
Hope it helps.

node.js and PostgreSQL query - throw new TypeError('first argument must be a string or Buffer');

I am trying to get a random geometry from a PostGIS enabled PostgreSQL database using nodejs, but when I attempt to even do the first query, to get the 'max' automatically-generated, sequential ID in the dataset, it throws the above error. I recognise that the error is because it's expecting a string rather than a numeric value, but as the 'gid' field is numeric, i'm not sure how to solve this.
Any help explaining the issue/fixing it so I can get my random object from the database would be extremely helpful. Thanks in advance.
var db = new pg.Client(conString);
db.connect();
function getRandObj(){
var max = db.query( " SELECT MAX(`gid`) FROM `buildings` ");
//var min = db.query( " SELECT MIN(`gid`) FROM `buildings` ");
//var random = mt_rand( min , max );
//var result = db.query( " ST_AsGeoJSON(geom) FROM `buildings` WHERE `gid` >= random LIMIT 0,1 ");
//return result
}
I haven't messed with node.js too much, but, I have experimented a little. Looking at your code here:
var max = db.query( " SELECT MAX(`gid`) FROM `buildings` ");
I see a couple of potential issues. First, the backquotes. I think they are a mistake. Change that query to read:
var max = db.query( " SELECT MAX(gid) FROM buildings ");
Or, if you really want to see quotes in there, you should be using "name" quotes, like:
var max = db.query( ' SELECT MAX("gid") FROM "buildings" ');
The second thing is the return value. I don't think you get direct returns like that. Have you tried something like this:
var max = -1;
q = db.query(' SELECT MAX("gid") FROM "buildings" as mx ');
q.on('row', function (row) {
console.log(row);
max = row.mx;
};
console.log("max is %d", max);
-g

SQL Parse Error when using node-mysql

I'm getting parse errors when I try to use node-mysql to invoke a query on a MYSQL database. I'm pretty sure that the query works. It runs without doubt via phpmyadmin.
Message.save = function(message, callback){
db.query("INSERT INTO e_message (chatid, message, userid) VALUES(" + message.chatid + ", '" + message.message +"', " + message.userid + "); SELECT * FROM e_message WHERE chatid = " + message.chatid + " ORDER BY timestamp DESC LIMIT 0, 1;",
function(err, rows, fields){
console.log(err);
callback(err, new Message(rows[0]));
});
}
I'm getting the follwing 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 'SELECT * FROM e_message WHERE chatid = 1 ORDER BY timestamp DESC LIMIT 0, 1' at line 1]
code: 'ER_PARSE_ERROR',
errno: 1064,
sqlState: '42000',
index: 0 }
The query looks like this via console.log():
INSERT INTO e_message (chatid, message, userid) VALUES(1, 'test123', 1);
SELECT * FROM e_message WHERE chatid = 1 ORDER BY timestamp DESC LIMIT 0, 1;
I don't know whats wrong with this...
EDIT:
If I split it into two queries, I get the result I wanted:
Message.save = function(message, callback){
db.query("INSERT INTO e_message (chatid, message, userid) VALUES(" + message.chatid + ", '" + message.message +"', " + message.userid + ");", function(err, rows, fields){
db.query("SELECT * FROM e_message WHERE userid = " + message.userid + " AND chatid = " + message.chatid + " ORDER BY timestamp DESC LIMIT 0, 1;", function(err, rows, filds){
callback(err, new Message(rows[0]));
});
});
}
Thank you!
node-mysql won't by default allow you to issue multiple SQL statements in a single query.
To allow that, you will need to set the multipleStatements connection option when creating the connection.
Note that allowing this may/will put you at risk of SQL injection, particularly if building the statements as strings. For example, if your message.userid was set to the string 1);drop database production;SELECT (, you'd be in trouble.
In this case what you really want may be to do the insert and a second SELECT LAST_INSERT_ID() to get the id the latest record was inserted with. It will return the latest inserted auto increment key for the session, that is, it will not be affected by other inserts by other connections/sessions.

Categories

Resources