You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React+Express服务器调用SQL Server存储过程提交数据

在Express中调用SQL Server存储过程的正确方式

你的代码存在几个关键问题,导致存储过程无法正确执行,下面是修正后的实现方案:

核心问题分析

  1. HTTP方法错误:提交数据应该用POST而非GET,GET请求不适合携带业务数据,且不符合REST语义。
  2. 存储过程调用方式错误:execute方法直接传入存储过程名称即可,不需要手动拼接exec语句;你当前的参数传递逻辑混乱,既用了.input()又在exec字符串里写参数,导致参数无法正确绑定。
  3. 未获取请求参数:代码里的@name、@res等参数没有从前端请求中读取,无法将页面数据传入存储过程。

修正后的代码示例

首先确保你已经安装了mssql包:

npm install mssql

然后修改路由实现:

// 改用POST路由接收页面提交的数据
app.post('/salesman_registration', async (req, res) => {
    let pool;
    try {
        pool = await sql.connect(conStr);
        
        // 从请求体中获取页面提交的参数
        const { name, res: parent, Address1, address2, address3 } = req.body;

        // 创建请求对象,逐个绑定存储过程需要的参数
        const request = pool.request();
        // 绑定存储过程的参数,参数名要和存储过程定义的完全一致
        request.input('ledcode', sql.Int, 0);
        request.input('ledname', sql.NVarChar, name);
        request.input('parent', sql.NVarChar, parent);
        request.input('add1', sql.NVarChar, Address1);
        request.input('add2', sql.NVarChar, address2);
        request.input('add3', sql.NVarChar, address3);
        request.input('StatementType', sql.NVarChar(50), 'Insert');

        // 直接调用execute方法,传入存储过程名称
        const result = await request.execute('Sp_LedgerRegistration');

        // 获取存储过程返回的最新编号
        const latestSlNo = result.recordset[0]?.latestSlNo || 0;

        res.status(200).json({ slNo: latestSlNo });
    } catch (err) {
        console.error('存储过程调用失败:', err);
        res.status(500).json({ message: '数据提交失败,请稍后重试' });
    } finally {
        if (pool) {
            await pool.close();
        }
    }
});

关键注意事项

  • 参数名匹配:.input()中的第一个参数必须和SQL Server存储过程定义的参数名完全一致(SQL Server默认不区分大小写,但建议严格匹配避免问题)。
  • 数据类型对应:第二个参数要指定正确的SQL Server数据类型(比如sql.Int、sql.NVarChar),确保和存储过程参数类型匹配。
  • 请求体解析:如果使用Express 4.16+,需要提前配置express.json()中间件来解析JSON格式的请求体:
    app.use(express.json());
    
  • 连接池优化:频繁创建和关闭连接池会影响性能,建议全局初始化一次连接池,而非每次请求都创建:
    // 全局初始化连接池
    const pool = new sql.ConnectionPool(conStr);
    pool.connect().then(() => console.log('数据库连接成功')).catch(err => console.error('连接失败:', err));
    
    // 路由中直接使用全局连接池
    app.post('/salesman_registration', async (req, res) => {
        try {
            const request = pool.request();
            // ... 参数绑定和执行逻辑
        } catch (err) {
            // ... 错误处理
        }
    });
    

内容的提问来源于stack exchange,提问作者aswin sivadas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 23:30:05