Simple postgres select query hangs forever when string passed as parameter - javascript

I am unable to figure out why the following query fails in node.js with pg PostgreSQL client (version 8.5.1).
db.query("SELECT id FROM my_table WHERE name LIKE $1", ["foo"], (error, results) => {
if (error) {
throw error
}
console.log(results.rows)
});
I do not get a error message and db.query function hangs forever.
However the following works, which I thought would be the same but I am obviously missing something:
db.query("SELECT id FROM my_table WHERE name LIKE 'foo'", ...
My table looks like this and have less then 10 rows:
CREATE TABLE IF NOT EXISTS my_table (
id SERIAL PRIMARY KEY,
name VARCHAR ( 128 ) UNIQUE NOT NULL
);
In case it is relevant, db.query is called from a express app endpoint handler. Also, passing parameters/values to INSERT statements works.
Edit: A prepared statement also works, still do not understand why above do not.
Any suggestions?

Related

How to escape single quotations (apostrophes) in MySQL query through Node.js?

I'm making a program where the user will enter data into inputs on a website. This information will then be relayed back to the server, using socket.io, and will be stored in a database. I am using this library to access MySQL from Node.js. Usually, when the user inputs the data, it is fine. But when the data includes single quotations, things aren't working. Here's an example:
let data = "LET'S GO";
// this is the data that the user inputs
// if it has single quotations in it, the code doesn't work
// otherwise it does
connection.getConnection(function(error, conn) {
if (error) throw error; // if there's an error while connecting, throw it
conn.query(
`INSERT INTO table_name (column) VALUES ('${data}')`, // make query with this MySQL call
function(err, result) {
conn.release();
if (err) throw err; // if there's an error with the call, throw it. Usually where my error comes
}
)
})
As commented in the code above, if the data variable has single quotations in it, the MySQL will return an error like the following:
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 's go.' at line 1
After initially running into this error, I've been looking for a solution. On this page, it says to use mysql.escape(), connection.escape() or pool.escape() to eliminate this issue. I've looked all over Stack Overflow solutions, but they all seem to point back to this. The issue with this solution is that the data is entered into the MySQL query with two single quotations around it. Therefore, the query looks a bit like this:
INSERT INTO table_name (column) VALUES (''DATA_HERE'')
Instead of:
INSERT INTO table_name (column) VALUES ('DATA_HERE')
In addition, I've looked at similar issues with mysql.escape(), connection.escape(), and pool.escape(), but they have been of no help because most of them do not have direct solutions.
Is there any OTHER way to escape these single quotations (apostraphes), if they were to appear in the data that the user inputs?
Thank you in advance. Any and all help is appreciated.
Alright, so it looks like I found an answer. My query has to be formatted in a way similar to prepared statements (thanks to #danblack for this). It should be done as such:
conn.query(
`INSERT INTO table_name (column) VALUES (?)`,
[data],
function(err, result) {
conn.release();
if (err) throw err;
}
)
I replaced '${data}' with ? and, in the next argument of the conn.query() function, I gave the value that ? should be replaced with.
If there is more than one data value that needs to be "escaped" in a similar way, you would do this:
conn.query(
`INSERT INTO table_name (column1, column2, column3) VALUES (?, ?, ?)`,
[data1, data2, data3],
function(err, result) {
conn.release();
if (err) throw err;
}
)
If anyone else happens to have a similar pending question, I hope this answers.
Note: this way of "escaping" doesn't only work with INSERT statements. I believe it can be used for all other queries.

node / express js, get data after query

I know it will be a trivial thing, but for this, I have not found much around, I'm using node/express js to query a database (MySQL), I'm using the following mode for queries:
index.js
exports.view= function(req, res){
var name = req.params.name;
req.getConnection(function(err,connection){
var query = connection.query('SELECT * FROM event WHERE linkname = ?',[name],function(err,rows)
{
if(err){
console.log("Error Selecting : %s ",err );
res.redirect('/');
}else{
console.log("rows: %s",rows);
var body = JSON.parse(JSON.stringify(rows));
console.log("body: %s",body);
res.render('form_payment',{page_title:"Showroom",data:rows});
}
});
});
};
I would like to view the video, or in any case be able to use part of the query data, I read that you can use JSON.stringify(), JSON.parse() or both, but I always print the empty string on the screen, even when I try to print rows:
rows:
body:
The query works perfectly, in fact, I can pass the json of rows to the next activity with res.render (), but in this function (view) I just can not get and then use this data. My idea would be to be able to easily use the contents of rows, for example, something like rows[0].name, rows[0].id or rows.name, rows.code, ...
[SOLVED]
Remember to check if the variables that are passed to the query are correct, once this problem has been solved everything is back to work correctly and access to the rows elements, can occur with rows[0].id, rows[0].name, ...
I hope you can also help you find yourself in this situation.

Node mssql: return id after SQL insertion

I am working on an integration between Mongodb and SQL Server, inserting and updating registers from MongoDb to SQL Server database with a scheduled process, using the mssql package to achieve this.
Each time a new register is inserted, I want the new row id to be retrieved back, because I need it to perform another insertions of subregisters.
I tried the following, expecting to have some information retrieved in the result of the query. The query actually inserts the row, but result is returned as undefined:
var sql = require('mssql');
var connectionConfig = 'xxxxxxxxxxxx';
var insertionQuery = 'xxxxxxxxxxxx';
sql.connect(connectionConfig).then(pool => {
pool
.request()
.query(insertionQuery);
}).then(result => {
//I expect 'result' to have information of the inserted row, but it comes undefined instead
cosole.log(result);
}).catch(err => {
console.err(err);
});
I think using stored procedures may work around this, but I just want to avoid using a stored procedure for simple inserts.
Does anyone knows how to have the new row id back after insertion?
EDIT
I did include OUTPUT SCOPE_IDENTITY() in my SQL statement - my query now looks like:
INSERT INTO TABLE (columns...)
OUTPUT SCOPE_IDENTITY()
VALUES (values...)
If I run the query in my SQL Server Management Studio, it works just fine and I got my new row id returned, but when running the query through the mssql package's query method, result is returned like this:
[ { '': null } ]
I quote from node-mssql insert returning undefined recordset:
INSERT statement doesn't return a recordset so recordset is
undefined. Please see this section of the docs to learn more
about how to get number of affected rows.
An option to solve this is to add a SELECT statement after your INSERT and ask for SCOPE_IDENTITY() or ##IDENTITY. That will get you the ID of the last inserted objects, i.e.:INSERT INTO table (...) VALUES (...); SELECT SCOPE_IDENTITY() AS id;
If anyone comes having problems with GUID, since you cannot set it as an Identity column, you must do something like:
const result = await pool
.request()
.input('orgName', sql.VarChar, orgName)
.input('tier', sql.Int, tier)
.input('status', sql.Int, status)
.input('createDate', sql.Date, new Date())
.input('statusChangeDate', sql.Date, new Date())
.query(`INSERT INTO app.Organizations (OrgName,
Tier, Status, CreateDate, StatusChangeDate)
OUTPUT inserted.OrgID
VALUES (#orgName, #tier, #status, #createDate, #statusChangeDate);
`)
Where the orgID is the auto generated GUID. Also don't follow my new Date() example as it inserts the date as tomorrow... I need to fix that.

KNEX Undefined binding(s) detected when compiling SELECT query

var knex = require('knex')(config);
var bookshelf = require('bookshelf')(knex);
var SKU = bookshelf.Model.extend({
tableName: 'skus',
});
SKU.where('id', undefined).fetch().then(function (skus) {
if (skus) console.log(skus.toJSON());
}).catch(function (err) {
console.error(err);
});
It throws
Undefined binding(s) detected when compiling SELECT query.
It is working fine with 0.11.5, it stopped working with 0.11.6 onwards. I am pointing to 0.13.0 right now.
useNullAsDefault: true
works fine with insert queries but not select queries. Is there any flag i should pass to resolve this error?
.where('id', undefined) does not mean anything in SQL. You cannot be querying something that is not there.
Maybe you wanted to query where id IS NULL? With knex it can be done like this: .whereNull('id')
With earlier knex versions it would have been just ignored, but starting from 0.12.x.
So to have equivalent functionality with newer (and actually it is compatible with older < 0.12 versions too) knex versions you should do:
SKU.fetch().then(function (skus) {
if (skus) console.log(skus.toJSON());
}).catch(function (err) {
console.error(err);
});
Unless bookshelf is adding some extra magic there...
The useNullAsDefault: true option Is used only for when inserting multiple rows in one insert. It does not make sense to use it unless you are using sqlite (check last example of http://knexjs.org/#Builder-insert).
parameter mismatch in payload
the parameter which sql query is expecting and the parameter you sending in requestbody is not matching.
in my case sql was expecting parameter "gradeId" but in requestBody i was sending "postId"

Node js mysql returns empty result when asking with AND operator

I have trouble with MySQL query in Node.js
This is my source code:
var passwordHash = sha512(data.passwordLogin).toString('hex');
database.query('SELECT `name`, `email`, `email-validated` FROM Players WHERE `email` = ? AND `password` = ?', [database.escape(data.name), database.escape(passwordHash)], function (error, results, fields) {
if(error)
logger.error(error);
else
{
logger.debug(results[0].name); //This line returns an empty array
}
});
It is working fine when I ask only for email, but with AND operator in query it returns an empty array as result.
Data given to query and data in database are equal.
Also trying to access something like results[0], results[0][0] or results[0].name causes server (app.js) to crash.
Any ideas to solve this? If you need more information about the source code just ask.
I really appreciate your help.

Categories

Resources