You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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.Intsql.VarChar(n)(n是长度,比如sql.VarChar(50))、sql.DateTimesql.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

火山引擎 最新活动