如何使用pg-promise为现有查询构建含动态WHERE条件列的条件AND查询
动态构建带参数的SQL查询函数
我来帮你搞定这个动态添加查询条件的问题,核心是要安全地构建参数化查询(避免SQL注入),同时动态根据obj的属性拼接条件。你的核心问题在于之前的写法没有正确处理动态条件的参数绑定,而且表名作为参数的写法在大多数SQL驱动里是不支持的(容易导致语法错误或注入风险),下面是修正后的完整方案:
解决方案代码
export async function find_items_based_on_params(category, type, obj) { // 第一步:转义表名(以PostgreSQL为例用双引号;MySQL请换成反引号`) // 这一步避免表名带来的SQL注入风险,同时保证语法正确 const escapedTable = `"${type}"`; // 初始化基础查询片段和参数数组 let queryParts = [ `SELECT * FROM ${escapedTable} INNER JOIN category ON category.cat_id = ${escapedTable}.category_id WHERE category.cat_type = $1` ]; let params = [category]; // 动态添加name条件(如果obj存在name属性) if (obj.name) { // 自动计算占位符编号,保证和参数数组对应 queryParts.push(`AND ${escapedTable}.name = $${params.length + 1}`); params.push(obj.name); } // 动态添加color条件(如果obj存在color属性) if (obj.color) { queryParts.push(`AND ${escapedTable}.color = $${params.length + 1}`); params.push(obj.color); } // 拼接完整查询语句并执行 const fullQuery = queryParts.join(' '); const res = await sql.query(fullQuery, params); return res; }
代码说明
- 表名转义:大多数SQL驱动不支持将表名作为参数(参数仅用于值),所以我们直接对表名进行转义,确保语法正确且避免注入风险。
- 动态条件拼接:用
queryParts数组累积查询片段,避免直接字符串拼接的混乱;用params数组动态添加参数,每个条件的占位符编号通过params.length + 1自动计算,保证参数和占位符一一对应。 - 属性检查:只有当
obj包含name或color属性时,才会添加对应的查询条件,完全符合你的需求。
示例效果
当你传入obj = { name: 'Brick', color: 'brown' }时,生成的查询语句会是:
SELECT * FROM "type值" INNER JOIN category ON category.cat_id = "type值".category_id WHERE category.cat_type = $1 AND "type值".name = $2 AND "type值".color = $3
对应的参数数组是[category, 'Brick', 'brown'],完美实现了你想要的动态条件效果。
注意事项
- 如果你的SQL驱动有专门的标识符转义方法(比如PostgreSQL的
pg库有client.escapeIdentifier()),建议用官方方法替代手动加双引号,兼容性更好。 - 永远不要直接拼接用户输入的字符串到SQL语句中,所有值都要通过参数绑定传递,这是防止SQL注入的关键。
内容的提问来源于stack exchange,提问作者Varian
相关产品推荐
相关产品推荐

