You need to enable JavaScript to run this app. NodeJS使用mssql操作SQL Server批量插入报错如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS使用mssql操作SQL Server批量插入报错如何解决?

mssql 批量插入实现方案

错误原因

你使用的INSERT INTO LOGIN (username, clave) VALUES ?是MySQL专属的批量传参语法,SQL Server 不支持该占位符用法,因此触发语法报错。

可用实现方案

方案1:表值参数(TVP,推荐)

这是SQL Server官方支持的批量插入方案,性能最优,也能避免SQL注入风险。
首先需要先在你的SQL Server数据库中执行一次语句创建自定义表类型:

CREATE TYPE LoginTableType AS TABLE (
    username VARCHAR(100),
    clave VARCHAR(100)
)

然后Node.js代码调整如下:

const sql = require('mssql');
const { database } = require('../keys');  

sql.connect(database, async function (err, con) {
    if (err) throw err;
    console.log("Connected!");
    
    // 构造表值参数
    const tvp = new sql.Table()
    // 列定义要和刚才创建的表类型对应
    tvp.columns.add('username', sql.VarChar(100))
    tvp.columns.add('clave', sql.VarChar(100))
    
    // 批量添加行数据
    const values = [
        ['John', 'Highway 71'],
        ['Peter', 'Lowstreet 4'],
        ['Amy', 'Apple st 652'],
        ['Hannah', 'Mountain 21'],
        ['Michael', 'Valley 345'],
        ['Sandy', 'Ocean blvd 2'],
        ['Betty', 'Green Grass 1'],
        ['Richard', 'Sky st 331'],
        ['Susan', 'One way 98'],
        ['Vicky', 'Yellow Garden 2'],
        ['Ben', 'Park Lane 38'],
        ['William', 'Central st 954'],
        ['Chuck', 'Main Road 989'],
        ['Viola', 'Sideway 1633']
    ]
    values.forEach(row => tvp.rows.add(...row))

    // 执行插入语句
    const request = new sql.Request()
    request.input('LoginData', tvp)
    const result = await request.query(`
        INSERT INTO LOGIN (username, clave)
        SELECT username, clave FROM @LoginData
    `)
    
    console.log("Number of records inserted: " + result.rowsAffected[0])
})

方案2:拼接VALUES子句(适合小数据量)

如果数据量不大(小于100条),可以直接拼接多组VALUES的写法,SQL Server支持INSERT INTO 表(列) VALUES (v1,v2),(v3,v4)...的语法:

const sql = require('mssql');
const { database } = require('../keys');  

sql.connect(database, async function (err, con) {
    if (err) throw err;
    console.log("Connected!");
    
    const values = [
        ['John', 'Highway 71'],
        ['Peter', 'Lowstreet 4'],
        // 剩余的业务数据
    ]
    // 生成占位符和参数列表
    const params = []
    const valuePlaceholders = values.map((row, idx) => {
        const userPlaceholder = `@username${idx}`
        const clavePlaceholder = `@clave${idx}`
        params.push({name: userPlaceholder, type: sql.VarChar(100), value: row[0]})
        params.push({name: clavePlaceholder, type: sql.VarChar(100), value: row[1]})
        return `(${userPlaceholder}, ${clavePlaceholder})`
    }).join(',')

    const request = new sql.Request()
    params.forEach(p => request.input(p.name, p.type, p.value))
    const result = await request.query(`
        INSERT INTO LOGIN (username, clave) VALUES ${valuePlaceholders}
    `)
    console.log("Number of records inserted: " + result.rowsAffected[0])
})

方案3:Bulk Insert(适合超大数据量)

如果需要插入上万条甚至更多数据,可以用mssql的bulk接口,性能更高:

const sql = require('mssql');
const { database } = require('../keys');  

sql.connect(database, async function (err, con) {
    if (err) throw err;
    console.log("Connected!");
    
    const bulk = new sql.Table('LOGIN')
    // 对应表的列,注意如果有自增主键要设置{ identity: true }
    bulk.columns.add('username', sql.VarChar(100), { nullable: false })
    bulk.columns.add('clave', sql.VarChar(100), { nullable: false })
    
    const values = [
        // 你的业务数据
    ]
    values.forEach(row => bulk.rows.add(...row))

    const result = await sql.bulk(bulk)
    console.log("Number of records inserted: " + result.rowsAffected)
})

内容的提问来源于stack exchange,提问作者Juan Castillo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 04:06:01