SQL Query getting escaped characters inserted - javascript

I have a query thats being fed into MySQL. I added a new component.. a LIKE.
It works fine for a singular item, but when I pass in multiples... it does some weird escape of the single quotes.
Here is what the sql passed in looks like (from the console.log below):
sql: 'select name, street, numbers from' +
"`HOMES` where " +
"year='2020' and vals in ('2.2.3\\',\\'2.4.5')",
values: [ '2020', "2.2.3','2.4.5"]
Here is how I build the vals:
sql += " and vals in (?)";
var newStr = filterText.myItems.split(",".join("','");
sqlParams.push(newStr);
filterText.myItems is entered by the user as a comma separated value. For example: "2.2.3,2.4.5"
The query going into MySQL is built like this:
exports.query = function(sql, params, resultHandler, errorHandler) {
function _handleError(err) {
errorHandler(config.mysql.errorMessage || err);
}
pool.getConnection(function(err, conn) {
if(err) {
_handleError(err);
return;
}
var query22 = conn.query(sql, params, function(err,results) {
if(err) {
_handleError(err);
} else {
resultHandler(results);
}
conn.release();
});
//this prints out the sql and values displayed above.
console.log("FINAL QUERY:"+util.inspect(query22));
}
}
Needless to say... this fails to execute as I guess MySQL has no idea what the \\' actually is.
For whatever reason the query adds the leading and trailing single quotes. This is why I add the ',' in between the numbers.
Anyone know what might be causing this or how I can remove it before it executes?
thanks!

After messing around some more I finally got it to work. Here is how.
The sql was built and params passed in like this:
sql = "select name, street, numbers from ?? where year=?",
sqlParams = [this.tableName, this.year]
I was dynamically adding to my sql with the in clause. However, when I made it part of the main sql and passed in the vals there it worked!
sql = "select name, street, numbers from ?? where year=? and vals in (?)",
sqlParams = [this.tableName, this.year, filterText.myItems.split(',')]
The sql going in now looks like this and works great:
sql: 'select name, street, numbers from' +
"`HOMES` where " +
"year='2020' and vals in ('2.2.3','2.4.5')",
values: [ '2020', ['2.2.3','2.4.5'] ]

Related

Query doesn't work if I move hardcoded quotation marks

Brief history
I have a JavaScript object which stores query templates with $nameParam so that it can be replaced with string.replace(). Issue is that until now I needed $nameParam to be in quotation marks and now I need to get rid of them. Depending on when they are added, the query either works or not. I have observed some interesting behaviour:
Method which replaces string
This method basically calls database and gets records. You can see the longest line - it's responsible for replacing $nameParam with the provided parameter.
function setupEndpoint(app) {
app.get('/neo4jdb/:queryType',
async (req, res) => {
const session = driver.session();
res.on('finish', () => session.close());
try {
const response = await session.run(queryTemplates[req.params.queryType],
{ nameParam: req.query.name });
let statement = response.summary.query.text.replace('$nameParam', `"${response.summary.query.parameters.nameParam}"`);
statement = statement.replace('RETURN', '\nRETURN');
console.info(`Neo4j statement: ${statement}`);
res.send({ rawItems: response.records, statement });
} catch (err) {
console.error('Error connecting Neo4j', configs);
console.error(err);
res.send({ error: 'Error connecting Neo4j' });
}
});
}
Working example
Query template
const queryTemplates = {
getShipsForCompany: `MATCH (A:Company) -[RELATIONSHIP]-> (B:Ship) MATCH (B:Ship)-[RD]-()
WHERE A.name=$nameParam RETURN B as Ship, A as Company, type(RELATIONSHIP) as R, count(RD) as degree limit 50`
};
Replacement
response.summary.query.text.replace('$nameParam', `"${response.summary.query.parameters.nameParam}"`);
Produced output
Neo4j statement: MATCH (A:Company) -[RELATIONSHIP]-> (B:Ship) MATCH (B:Ship)-[RD]-() WHERE A.name="TRINITY HOUSE"
RETURN B as Ship, A as Company, type(RELATIONSHIP) as R, count(RD) as degree limit 50
Not-working example
Query template
const queryTemplates = {
getShipsForCompany: `MATCH (A:Company) -[RELATIONSHIP]-> (B:Ship) MATCH (B:Ship)-[RD]-()
WHERE A.name="$nameParam" RETURN B as Ship, A as Company, type(RELATIONSHIP) as R, count(RD) as degree limit 50`
};
Replacement
response.summary.query.text.replace('$nameParam', `${response.summary.query.parameters.nameParam}`);
Produced output
Neo4j statement: MATCH (A:Company) -[RELATIONSHIP]-> (B:Ship) MATCH (B:Ship)-[RD]-() WHERE A.name="TRINITY HOUSE"
RETURN B as Ship, A as Company, type(RELATIONSHIP) as R, count(RD) as degree limit 50
Summary
Both produced output queries are the same. Why first one returns results and second one is empty? (2nd one copied to DB engine works fine)
Neo4j cypher syntax is below.
WHERE A.name=$nameParam
It should NOT have double quotes on the parameter name. Thus, the 2nd example is syntax error during runtime.

Swedish characters from javascript to mssql - appear as question marks in db table?

So I have this weird issue with node js right now and can not find any solution...
Im trying to insert values to my mssql table and some of the values includes the swedish characters "åäö". Anyhow when I do this they appear as "??????". Each special character appear as two question marks ("ö" -> "??").
Some details:
*Package I'm using is in js: msnodesqlv8
var sql = require('msnodesqlv8');
const connectionString = "server=host;Database=MyDb;Trusted_Connection=Yes;Driver={SQL Server Native Client 11.0}"
q = "Insert into [MyDb].[dbo].[MyTable] (testCol) values ('ö')"
sql.query(connectionString, q, (err,data) => {
if (err) {
console.log(err);
}
else {
console.log('Imported row to table.');
}
})
*The columns in the db table that will retrieve values containing "åäö" is defined as datatype nvarchar(50)
I have also trid with N'ö' in variable q and these characters (within the double quotes) appear in db table "ᅢᄊ"
*console.log('ö') prints ö in console as expected
*I have tried all conversions i can think about in js (for example utf-8, latin1, etc...)
*Collation in db is Finnish_Swedish_CI_AS
*I have tried to read out swedish chrs from another table and it works fine through the package msnodesqlv8
The problem to me seems to be somewhere when sending the query from js (everything looks fine here), through package msnodesqlv8 and when mssql shall interpret the values. Im very glad if someone can help me.
Is there some reason you're not using a prepared statement? It takes care of the encoding for you, e.g.:
const sql = require('msnodesqlv8')
const connectionString = "server=YourServerIp,YourServerPort;Database=StackOverflow;Trusted_Connection=Yes;Driver={SQL Server Native Client 11.0};"
console.log('Connecting...')
sql.open(connectionString, (err, conn) => {
console.log('Dropping...')
conn.query('drop table if exists [dbo].[Swedish]', (err,) => {
console.log('Creating...')
conn.query('create table [dbo].[Swedish] (testCol nvarchar(50))', (err) => {
console.log('Inserting...')
conn.prepare('insert [dbo].[Swedish] (testCol) values (?)', (err, ps) => {
ps.preparedQuery(['ö'], (err) => {
ps.free();
console.log('Selecting...')
conn.query('select * from [dbo].[Swedish]', (err, rows) => {
console.log(`${JSON.stringify(rows)}`)
})
})
})
})
})
})
Which yields...
> node .\swedish.js
Connecting...
Dropping...
Creating...
Inserting...
Selecting...
[{"testCol":"ö"}]
The same character is present when queried via SSMS.

Sequelize query string prefix / starts with

I'm building an autofill function that takes a string input and returns a list of string suggestions.
Sequelize's iLike:query returns every string in which the queried string appears. I would like to favour strings for which the query is a prefix. For example when query='sh' then the results should return strings that start with sh instead of having sh anywhere within the string.
This is relatively simple to do after receiving the data from the DB, however I was wondering if there is a way to accomplish this via sequelize while querying the DB? If so how?
The DB size will be between 10,000 and 100,000 strings of no more than a handful of words (company names to be exact).
Optional question: DB's usually have superior performance to generically written code, in this circumstance should there even be a noticeable difference? Or should I just collect all the data from the DB and apply some other filters on it after via vanilla JS.
let suggestions = yield db.Company.findAll({
limit: 7,
where: {
company_name: {
$iLike: '%'+this.data.query
}
}
})
Seems like this is super easy! The '%' acts like a * from regex. So query + '%' returns any results where query is the prefix.
let suggestions = yield db.Company.findAll({
limit: 5,
where: { $or: [
{ stock_ticker: { $ilike: query + '%' } },
{ company_name: { $ilike: query + '%' } }
]},
order: '"volume" DESC'
})

Limit date format in node.js

I'm using Node.js together with mysql, express and html.
When I'm retrieving the results from the database I get the following date,
2016-03-16T00:00:00.000Z, even though the type in mysql is date.
My query:
app.get('/list', function (req,res) {
connection.query('SELECT `ondate`,`projectname`,`hours` FROM `entries` WHERE YEARWEEK(`ondate`, 1) = YEARWEEK(CURDATE(), 1) ORDER BY ondate DESC ,projectname ASC ', function(err, rows, fields) {
res.json({error: err, result: rows});
});
})
Is there a way I can set the ondate field to ignore the time?
Use this:
SELECT
DATE_FORMAT(`ondate`,'%m-%d-%Y'),
`projectname`,
`hours`
FROM `entries`
WHERE YEARWEEK(`ondate`, 1) = YEARWEEK(CURDATE(), 1)
ORDER BY ondate DESC, projectname ASC;
Adjust the date format to the one you need.
Regards
Hard to know exactly where the unwanted formatting is being introduced, but it might be an option to remove it as part of post processing rows...
// Assuming array of rows takes shape something like this...
var rows = [{ondate:'2012-01-02T00:00:00.000Z'},{ondate:'2013-01-02T00:00:00.000Z'},{ondate:'2012-03-02T00:00:00.000Z'}];
// map rows to show only first ten chars of `ondate` field
rows = rows.map(function(item){ return item.ondate.slice(0,10); });
// business as usual...
alert(rows);
//-> 2012-01-02,2013-01-02,2012-03-02

WebSQL: Error processing SQL: number of '?'s in statement string does not match argument count

I want to create a dynamic function to INSERT data into the webSQL Database. I cannot use indexed DB because Zetakey does not support it.
tx.executeSql("INSERT INTO " + table + "(" + formatfields + ")
VALUES (" + formatqm + ")",
[formatvalues],
webdb.onSuccess,
webdb.onError);
Ich übergebe an den Query:
formatfields = "one, two"; (up to an undefined number)
formatqm = "?, ?";
formatvalues = "123, 456"; (dynamic user entries for x fields)
Can someone tell me what do I have to do with the formatvalues? When I write 123, 456 directly its working fine.
Thanks in advance!
Instead of dynamically create or change table column fields, use JSON serialization of the record. Basically store stringify user given object data on INSERT and parse on retrieval. If you need query over column, initialize those columns only. It will be just like IndexedDB does.
/*array.push */
formatvalues = new Array;
formatvalues.push("123");
and so on!

Categories