Reputation: 97
I currently have the following function that works perfectly fine:
const sql = require('mssql');
const config = require('../../config/credentials');
const Hardware = function () { };
Hardware.prototype.create = function (body) {
return new sql.ConnectionPool(config).connect().then(function (pool) {
return pool.query
`SELECT *
FROM my_table
WHERE hardware_guid = ${id}
});
};
But I want "my_table" in the query to be a variable, like ${my_table}. If I do it in the same way, I get the following error:
Must declare the table variable "@param1"
Looking at the documentation of the mssql package (https://www.npmjs.com/package/mssql), specifically at the section of ConnectionPool, I can see that they declare this parameters in the following way:
const sql = require('mssql')
sql.connect(config).then(pool => {
// Query
return pool.request()
.input('input_parameter', sql.Int, value)
.query('select * from mytable where id = @input_parameter')
}).then(result => {
console.dir(result)
}).catch(err => {
// ... error checks
})
sql.on('error', err => {
// ... error handler
})
So I tried to do something similar, this is what I did:
var sql = require("mssql")
var config = require("./test");
var id='1'
const pool1 = new sql.ConnectionPool(config);
pool1.connect().then(pool => {
return pool1.request() // or: new sql.Request(pool1)
.input('mytable', sql.NVarChar, 'nvs_central.software_governance')
.query(`SELECT *
FROM @mytable
WHERE software_guid = ${id}`)
}).then(result => {
console.dir(result)
}).catch(err => {
console.dir(err)
});
pool1.on('error', err => {
console.dir(err)
});
But I still get the "Must declare the table variable "@mytable" error. Note that if I replace "@mytable" in that last piece of code for "my_table_name" (so I put the actual name of the table instead of a variable/parameter) it retrieves the expected data perfectly fine.
So what do I need to do?
Thanks!
Upvotes: 6
Views: 4652
Reputation: 2990
You can still use the .inputs
to protect you against SQL injections; you just need to pump them through EXEC()
in a stringified form:
const result = await pool.request()
.input("TableName", $ddi.app.services.sql.lib.VarChar(50), oData.TableName)
.input("TableColumn", $ddi.app.services.sql.lib.VarChar(50), oData.TableColumn)
.input("ID", $ddi.app.services.sql.lib.VarChar(50), oData.ID)
.query(`
EXEC('SELECT ' + @TableColumn + ' FROM ' + @TableName + ' WHERE ' + @TableColumn + ' = ' + @ID + ';');
`)
;
Upvotes: 3
Reputation: 3621
I inserted the table name the 'oldschool' way:
const queryString = "SELECT * FROM DocuManager." + tableName + " WHERE id = @id";
const result = await pool.request()
.input('id', sql.Int, id)
.query(queryString);
That works fine.
Upvotes: 3
Reputation: 460
in sql server @table_name means it is a temporary table variable. you are essentially telling it that you have declared a variable temporary table and you want to select from that. so it attempts to look for it in tempdb and when it doesn't find it, it throws a syntax error.
you will need to switch it back to the "working" example way if you want it to work as using @table in the from clause makes sql server assume you are using a variable temp table.
Upvotes: 2