I have a Typescript application that interacts with a Microsoft SQL Server database and I am using the node mssql
package to interact with it (to be precise, I am using the connection pool from a version of that package that allows for multiple databases to be connected):
import * as sql from "@cityssm/mssql-multi-pool";
import mssql from 'mssql';
I have the following function that creates dynamic queries:
function assembleInOutQuery(from: string, to: string, accounts: string[]): string {
const base = `--sql
SELECT
beleg AS receiptId,
"index",
fhaben,
text,
konto AS account,
amount AS value,
date
FROM dbo.Buchung
WHERE date >= '${from}' AND date <= '${to}' AND `
let accString = `(konto = ${accounts.shift()}`
for (const acc of accounts) {
accString = accString + ` OR konto = ${acc}`
}
accString = accString + ")"
return base + accString
}
This code produces valid queries as accounts always contains at least one value. However, when executed through the node mssql
package it produces the wrong output as the first value in accounts
is always ignored. Due to this problem, I had to change it to the following function in order to produce the expected behaviour, however this is not a very good solution as it only circumvents the problem instead of solving it:
function assembleInOutQuery(from: string, to: string, accounts: string[]): string {
let query = `SELECT
beleg AS receiptId,
"index",
fhaben,
"text",
konto AS account,
amount AS "value",
date
FROM dbo.Buchung
WHERE (date >= '${from}' AND date <= '${to}') AND (konto = '0'`
for (const acc of accounts) {
query = `${query} OR konto = '${acc}'`
}
query = `${query});`
return query
}
I had to include the (konto = '0'
part because this part of the query seems to be dropped. It does not matter whether I put this part of the condition first in the WHERE clause or after the date being checked, the first value of "konto" I constrain on, is always dropped. Does anyone have an explanation why this happens?
I was not able to reproduce this behaviour in Microsoft SQL Server Management Studio, as there the query is executed exactly the way it is written. I checked the output of the function and executed it in Microsoft SQL Server Management Studio where it ran without problems and generated the expected output. When executed inside the application using the mssql
package, the (konto = '0'
part needs to be added for the output to be as expected.
Could this be due to some internal SQL injection protection the prevents certain parts of the query from being executed?
If anyone has suggestions as to how I can improve the above mentioned approach for generating the dynamic queries in a better/safer way, I'd also greatly appreciate it.
Thank you