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

Node.js中如何将req参数传入SQL查询函数?

问题分析

你遇到的核心问题是异步操作的处理错误和变量作用域混乱:

  1. 最初的getInfo函数是异步执行的,但你同步调用后直接渲染视图,此时查询还没完成,数据根本没拿到;而且函数内部的camInfo是局部变量,外部完全访问不到。
  2. 尝试async/await时用法错误——mysqlConf.getConnection是回调式API,不能直接await,必须先包装成Promise才能配合异步语法使用。
  3. 代码里存在变量名混淆(比如results未声明就使用、result重复定义)、错误抛出方式错误(throw new err()是无效写法)等细节问题。
解决方案

把MySQL的回调式API包装成Promise,用async/await规范处理异步逻辑,同时将查询函数封装成独立的、接收明确参数的模块。

步骤1:包装MySQL API为Promise

Node.js内置的util.promisify可以快速把回调函数转成Promise:

const util = require('util');
// 把getConnection和query方法转成Promise版本
const getConnection = util.promisify(mysqlConf.getConnection.bind(mysqlConf));
const query = util.promisify((connection, sql, params) => connection.query(sql, params));

步骤2:封装查询函数

不需要传递整个req,直接传需要的product_code更清晰:

// 获取相机基础信息
async function getCameraInfo(productCode) {
  let connection;
  try {
    connection = await getConnection();
    // 按product_code查询,结果应该只有一条,直接取rows[0]
    const rows = await query(connection, 'SELECT * FROM camera_info WHERE product_code = ?', [productCode]);
    return rows[0] || null;
  } catch (err) {
    console.error('获取相机信息失败:', err);
    throw err; // 抛出错误让上层处理
  } finally {
    if (connection) connection.release(); // 确保数据库连接释放
  }
}

// 获取相机功能列表
async function getCameraFeatures(productCode) {
  let connection;
  try {
    connection = await getConnection();
    const rows = await query(connection, 'SELECT * FROM cam_features WHERE product_code = ?', [productCode]);
    return rows; // 返回所有功能条目
  } catch (err) {
    console.error('获取相机功能失败:', err);
    throw err;
  } finally {
    if (connection) connection.release();
  }
}

步骤3:修改路由处理逻辑

用async/await等待两个查询完成,再渲染视图:

app.get('/product-page/:product_code', async (req, res) => {
  try {
    const productCode = req.params.product_code;
    // 并行执行两个查询,提升性能
    const [cameraInfo, cameraFeatures] = await Promise.all([
      getCameraInfo(productCode),
      getCameraFeatures(productCode)
    ]);

    // 如果相机不存在,返回404
    if (!cameraInfo) {
      return res.status(404).send('该相机不存在');
    }

    // 把两个表的数据传给视图
    res.render('test-view', { info: cameraInfo, features: cameraFeatures });
  } catch (err) {
    console.error('路由处理失败:', err);
    res.status(500).send('服务器内部错误');
  }
});

额外优化点

  • 视图里可以直接用<%= info.xxx %>调用相机基础信息,用<% features.forEach(feature => { %> ... <% }) %>遍历功能列表。
  • 避免全局变量污染,所有变量都用let/const声明。
  • 统一错误捕获,防止单个查询失败导致服务器崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:31:25