How to extract the query string from a SQLite object in nodejs?
For example if we have this:
import sqlite3 from 'sqlite3';
import { open } from 'sqlite';
const db = await open({
filename: 'test.db',
driver: sqlite3.Database
});
var ret = await db.get('SELECT * FROM `test` WHERE id=? AND foo=?', [100, 'bar']);
How can we achieve this:
SELECT * FROM `test` WHERE id="100" AND foo="bar"
I expect something like this to happen:
db.getQueryString();
es6 string replacement is supporet by nodesjs.
var my_id = 100
var my_var = 'bar';
var s = `SELECT * FROM `test` WHERE id="${my_id}" AND foo="${my_var}" `;
console.log(s);
But you should prepare your statements to make the secure like https://stackoverflow.com/a/49328621/5193536
Depending if ydo want the strings in the log to be used, for testing, you must add single quotes to the sting above, which the query makes automatically
Related
I was trying to query my (postgres) db with a customizable statement built front end.
My resolver gets the built query inside the input param, but when I use the queryRaw method I get this error:
`"\nInvalid `prisma.queryRaw()` invocation:\n\n\n Raw query failed. Code: `42601`. Message: `db error: ERROR: syntax error at or near \"$1\"`"`
Is there a way to build a custom query and pass it like the input variable WITHOUT USING queryRawUnsafe to prisma? (queryRawUnsafe works fine, but well.. it's unsafe XD) Thanks <3
Here is my code.
getCars: (_parent, { input }, { prisma }) => {
if(input){
console.log(input) // --> SELECT * FROM car WHERE car."plate" ILIKE '%123%' //type String
const differentInput = '%123%'
// const result = prisma.$queryRaw`SELECT * FROM car WHERE car."plate" ILIKE '%123%'` // works
// const result = prisma.$queryRaw`SELECT * FROM car WHERE car."plate" ILIKE ${differentInput}` // works
// const result = prisma.$queryRawUnsafe(input) // works
const result = prisma.$queryRaw`${input}` // Doesn`t work
return result
}
// ... Other code
}
prisma.$queryRaw only accepts templated strings, not just strings. You can use the Prisma.sql helper to generate those templated strings to get the expected results. That might look like:
const sql = Prisma.sql`SELECT * FROM car WHERE car."plate" ILIKE '%123%'`
const result = prisma.$queryRaw`${sql}`
The queryRaw documentation mentions Prisma.sql with other examples but doesn't show any examples of what you are trying to do.
I have 2 arrays, the first one contains the columns for the insert and the second one contains de values
const columns = ['columnName1','columnName2','columnName3','columnName4','columnName5','columnName6'];
const values2 = ['test1', 'test2', 27, 1, 'an address', null];
module.exports = {columns, values2}
And I'm trying to do the insert using mmsql library but not even the documentation contains a sample with multiple columns to insert values to.
This is a sample of my insert
let pool = await sql.connect(config)
const result = await pool.request().query(`INSERT INTO [Test].[TableName] (${testData.columns}) VALUES ?`, [[testData.values2]]);
console.dir(result);
And I'm getting the following error:
RequestError: Incorrect syntax near '?'.
I was able to select to the db with no issues but there's something about the syntax that it doesn't seem to like..
At least you forgot to wrap ? with round brackets:
const result = await pool.request().query(`INSERT INTO [Test].[TableName] (${testData.columns}) VALUES (?)`, [[testData.values2]]);
As I can't find a single example, where you pass the parameters of your sql-query to the query function or use ? as a placeholder in their documentation, I'm not sure, whether node-mssql supports this. But if it does, you should at least create as many ? in the sql statement as you add values.
var cols = [...]; //your columns
const sqlquery = `insert into sometable (${cols}) values (${new Array(cols.length).fill('?')})`;
The documented way would be using input parameters
await pool.request()
.input('p1', sql.Int, value1)
.input('p2', sql.VarChar(50), value2)
.query('insert into sometable(col1, col2) values(#p1, #p2)');
To keep this flexible you could use something like the following
var cols = ['col1', 'col2'];
var vals = ['a string', 23];
const request = pool.request();
for (let i = 0; i < vals.length; i++)
request.input(`param_${i}`, vals[i]); //if you skip the parametertype, mssql will guess it from the value
const sqlquery = `insert into sometable(${cols}) values (${vals.map((_,i) => `#param_${i}`)`;
const result = await request.query(sqlquery);
I want to make use of SELECT and IN to match on values between tables from two different SQL databases in my Node app that makes use of the mssql package:
My question is, if I am passing a variable representing that array of values in my Node app, that looks like this:
const arr = ["1323", "2311", "1234"];
would I do this?:
N'[arr]'
or this?
N'arr'
Or is there some other syntax I should use?
Right now, this is the full query I'm passing:
// An array *like* this, saved in a variable name:
const sourceIdArr = ["1323", "2311", "1234"];
const selectInQuery = `
DECLARE #sourceIdArr NVARCHAR(4000) = N 'sourceIdArr'
SELECT NDID FROM SR_Empsheets
WHERE NDID IN ( SELECT value from openjson(#sourceIdArr) )
`;
Will this work, or should I approach it differently?
So something like
const sourceIdArr = ["1323", "2311", "1234"];
const selectInQuery = `
SELECT NDID FROM SR_Empsheets
WHERE NDID IN ( SELECT value from openjson(#sourceIdArr) )
`;
new sql.Request()
.input("sourceIdArr", sql.VarChar(sql.MAX), JSON.stringify(sourceIdArr) )
.execute(selectInQuery , (err, result) => {
// ... error checks
console.dir(result)
});
I am trying to make a search bar which works with multiple words, but I am worried about SQL injection.
I am using node express with the npm mssql package.
Here's the code which gets the criteria, generates the SQL and runs it:
router
.get('/search/:criteria', function (req, res) {
var criteria = req.params.criteria;
var words = criteria.split(" ");
var x = ""
words.map(word => x += `name like '%${word}%' and `);
x = x.substring(0, x.length - 5); // Remove trailing 'and'
var query = `SELECT * FROM table WHERE ${x}`
new sql.ConnectionPool(db).connect().then(pool => {
return pool.request().query(query)
}).then(result => {
})
});
A search for something to search would result in this query:
SELECT * FROM table
WHERE
name like '%something%'
and name like '%to%'
and name like '%search%'
I tried some SQL injections myself, but none of them seem to work.
Note: I am aware that we should always use inputs for this. It works fine for one word, but I don't know how to use inputs for many words. Ex:
new sql.ConnectionPool(db).connect().then(pool => {
return pool.request()
.input('input', '%'+criteria+'%')
.query(query)
})
The answer is: It's not safe. Your code does exactly nothing to make it safe, either. Don't build SQL by concatenating/interpolating user-supplied data into the statement.
In addition, you don't do any escaping for LIKE itself, either, so that is just as unclean.
If you need dynamic SQL, build a prepared SQL statement with the expected number of placeholders and then bind user-supplied values to those placeholders.
router.get('/search/:criteria', (req, res) => {
const ps = new sql.PreparedStatement();
const sqlConditions = [];
const escapedValues = {};
// set up escaped values, safe SQL bits, PS parameters
req.params.criteria.split(" ").forEach((v, i) => {
const paramName = 'val' + i;
escapedValues[paramName] = v.replace(/[\\%_]/g, '\\$&');
sqlConditions.push(`name LIKE '%' + #${paramName} + '%' ESCAPE '\'`);
ps.input(paramName, sql.VarChar);
});
// build safe SQL string, prepare statement
const sql = 'SELECT * FROM table WHERE ' + sqlConditions.join(' AND ');
ps.prepare(sql);
// connect, execute, return
ps.execute(escapedValues).then(result => {
res(result)
});
});
(Disclaimer: code is untested, as I have no SQL Server available right now, but you get the idea.)
I use SQLite.swift and want to replace the question marks in a statement. This can be done for single entries like this:
let stmt = db.prepare("INSERT INTO users (email) VALUES (?)")
for email in ["betty#icloud.com", "cathy#icloud.com"] {
stmt.run(email)
}
I did not see how I can do the following to use a array like:
var values:[String] = ["test1","test2", "test3"]
in a Statement like:
let stmt = db.prepare("SELECT * from users where email in (?)")
The following does not work:
stmt.run(values)
How do I use an NSArray as an argument for a statement?
If you're using the type-safe layer, you can use contains():
users.filter(contains(["test1", "test2"], email))
// the above assumes this boilerplate precedes it:
let email = Expression<String>("email")
let users = db["users"]
If you're using the raw SQLite3 API, it does not support arrays, so you'll need to format those yourself:
let emails = ["test1", "test2"]
let template = join(", ", [String](count: count(emails), repeatedValue: "?"))
let stmt = db.prepare(
"SELECT * FROM users WHERE email IN (\(template))", emails
)