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);
Related
I have a .sql file containing a query such as
SELECT * WHERE id IN ($1)
The sql query is read and passed into a typeorm query with an array of parameters.
const result = await this.entityManager.query(myQuery, parameters);
I would like to have parameters be an array with a single value that would be a string concatenation of all the ids I want to find.
This would allow me to use my sql file no matter the number of ids I want to filter by.
I have tried formatting parameters in such a way that I can have $1 only no matter the number of items in my array:
const ids = ['1', '2', '3'];
const parameters = [ids.join("', '")];
or
const parameters = ["'" + ids.join("', '") + "'"];
etc
I have not found a syntax that works.
Is this feasible somehow ?
I have replaced the IN ($1) by = ANY($1) and am now passing the ids as an array. This works as I intend.
SELECT * WHERE id = ANY($1);
const ids = ['1', '2', '3'];
const result = await this.entityManager.query(myQuery, [ids]);
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
I am trying to insert into a table called Observations, I need to insert 10 rows using for loop, I have an array of 10 values that need to be inserted in a column called sens_value which is an INT type. I have tried the following code but it cant take sensValues[i] as an INT.
I am using noodjs to insert into tables using mariadb database.
Basically I am looking for a way to insert different INT values into my SQL statement using for loop. I tried the following code:
const mariadb = require('mariadb/callback');
const dbConn = mariadb.createConnection({host: 'localhost', user:'tudublin', password: 'tudublinpwd', database: 'IoT'});
var sensValues = [10,20,30,15,18,22,28,33,16,40];
for (var i in sensValues) {
console.log(sensValues[i]) //10,20,30,15,18,22,28,33,16,40
var sql = "INSERT INTO Observations (sensor_id, sens_value, sens_units, dt_added) VALUES (2, sensValues[i], 'C Deg per Volt', now());";
dbConn.query(sql, insertCallback)
}
function insertCallback(err, res) {
if (err) {new Date().getTime()
console.log(err.message);
} else {
console.log(res);
dbConn.end();
}
}
The sensValues[i] in the VALUES is treated as a string, not as a value from the array. Pass it on as a parameter:
var sql = "INSERT INTO Observations (sensor_id, sens_value, sens_units, dt_added) VALUES (2, ?, 'C Deg per Volt', now());";
dbConn.query(sql, [sensValues[i]], insertCallback)
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.)