如何在Node.js Express应用中使用mssql包执行SQL Server存储过程
嘿,刚接触Node.js + Express + SQL Server的组合确实需要慢慢摸清楚,我帮你把用mssql包调用存储过程的步骤讲得明明白白,包括怎么引用存储过程、传递各种类型的参数,看完就能上手啦!
先确认基础准备
首先得确保你已经安装了mssql包,如果还没装,跑这个命令:
npm install mssql
另外,你得有一个能正常连接SQL Server的配置,比如:
const sql = require('mssql'); const dbConfig = { user: '你的数据库用户名', password: '你的数据库密码', server: '数据库服务器地址', // 比如localhost或者远程IP database: '目标数据库名称', options: { encrypt: true, // 如果是Azure SQL需要开启,本地的话可以设为false trustServerCertificate: true // 本地测试可以开启,避免证书问题 } };
调用存储过程的核心方法
mssql包调用存储过程主要靠request()对象的execute()方法,下面分不同场景给你示例:
1. 调用无参数的存储过程
假设你有一个名为GetAllUsers的存储过程,用来查询所有用户数据,代码如下:
async function getAllUsers() { try { // 建立连接 await sql.connect(dbConfig); // 创建请求对象 const request = new sql.Request(); // 执行存储过程,直接传入存储过程名称 const result = await request.execute('GetAllUsers'); // 结果在result.recordset里,这是返回的数据集 console.log('查询结果:', result.recordset); return result.recordset; } catch (err) { console.error('调用存储过程出错:', err); throw err; } finally { // 确保连接关闭 await sql.close(); } }
2. 调用带输入参数的存储过程
比如有个GetUserById的存储过程,需要传入UserId参数,类型是int:
async function getUserById(userId) { try { await sql.connect(dbConfig); const request = new sql.Request(); // 用input()方法添加输入参数:参数名、数据类型、参数值 request.input('UserId', sql.Int, userId); // 执行存储过程 const result = await request.execute('GetUserById'); return result.recordset[0]; // 假设返回单个用户 } catch (err) { console.error('出错:', err); throw err; } finally { await sql.close(); } }
常用的数据类型有sql.Int、sql.VarChar(n)(n是长度,比如sql.VarChar(50))、sql.DateTime、sql.Bit等等,对应SQL Server里的类型。
3. 调用带输出参数的存储过程
比如有个GetUserCount的存储过程,通过输出参数TotalCount返回用户总数:
async function getUserCount() { try { await sql.connect(dbConfig); const request = new sql.Request(); // 用output()方法添加输出参数:参数名、数据类型 request.output('TotalCount', sql.Int); // 执行存储过程 await request.execute('GetUserCount'); // 输出参数的值在request.output里 console.log('用户总数:', request.output.TotalCount); return request.output.TotalCount; } catch (err) { console.error('出错:', err); throw err; } finally { await sql.close(); } }
4. 调用带返回值的存储过程
有些存储过程会用RETURN语句返回值(比如执行状态),这种情况需要用returnValue()方法:
async function AddNewUser(username) { try { await sql.connect(dbConfig); const request = new sql.Request(); request.input('Username', sql.VarChar(50), username); // 注册返回值,默认是int类型 request.returnValue(); await request.execute('AddNewUser'); // 返回值在request.returnValue里 console.log('存储过程返回值:', request.returnValue); return request.returnValue; } catch (err) { console.error('出错:', err); throw err; } finally { await sql.close(); } }
集成到Express接口里
把上面的逻辑放到Express路由里,比如:
const express = require('express'); const app = express(); app.use(express.json()); // 获取所有用户的接口 app.get('/users', async (req, res) => { try { const users = await getAllUsers(); res.status(200).json(users); } catch (err) { res.status(500).json({ message: '获取用户失败', error: err.message }); } }); // 根据ID获取用户的接口 app.get('/users/:id', async (req, res) => { try { const user = await getUserById(parseInt(req.params.id)); if (user) { res.status(200).json(user); } else { res.status(404).json({ message: '用户不存在' }); } } catch (err) { res.status(500).json({ message: '获取用户失败', error: err.message }); } }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`服务器运行在端口${PORT}`); });
一些注意事项
- 存储过程名称一定要拼写正确,区分大小写吗?要看你的SQL Server设置,一般建议和数据库里的名称完全一致。
- 参数名也要和存储过程里定义的参数名一致,比如存储过程里是
@UserId,你在代码里写UserId就行,mssql会自动加上@前缀。 - 尽量用
async/await语法,避免回调地狱,代码更清晰。 - 一定要在
finally块里关闭连接,或者可以用连接池(sql.ConnectionPool)来管理连接,更高效,不过刚入门先从基础的连接方式开始就行。
内容的提问来源于stack exchange,提问作者Niranjan A




