如何在node.js MSSQL中使用变量表名执行查询?

时间:2017-09-06 20:06:14

标签: sql sql-server node.js

我目前有以下功能完美无缺:

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}
    });
};

但我想" my_table"在查询中是一个变量,比如$ {my_table}。如果我以同样的方式执行此操作,则会收到以下错误:

  

必须声明表变量" @ param1"

查看mssql包(https://www.npmjs.com/package/mssql)的文档,特别是在ConnectionPool的部分,我可以看到它们以下列方式声明了这些参数:

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 
})

所以我尝试做类似的事情,这就是我所做的:

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)
});

但我仍然得到"必须声明表变量" @ mytable"错误。请注意,如果我更换" @ mytable"在#34; my_table_name"的最后一段代码中(所以我把表的实际名称而不是变量/参数)它完全检索预期的数据。

那么我需要做什么?

谢谢!

3 个答案:

答案 0 :(得分:1)

在sql server中@table_name表示它是一个临时表变量。你基本上告诉它你已经声明了一个变量临时表,你想要从中进行选择。所以它试图在tempdb中查找它,当它找不到它时,它会抛出语法错误。

你需要将它切换回"工作"示例方式如果您希望它在from子句中使用@table工作,则sql server假定您使用的是变量临时表。

答案 1 :(得分:1)

我将表名称插入'oldschool'方式:

const queryString = "SELECT * FROM DocuManager." + tableName + " WHERE id = @id";

const result = await pool.request()
    .input('id', sql.Int, id)
    .query(queryString);

工作正常。

答案 2 :(得分:0)

您仍然可以使用.inputs来防止SQL注入;您只需要以字符串形式通过EXEC()泵送它们:

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 + ';');
    `)
;