如何通过绑定node.js-sql中的参数来构建动态查询?

Ban*_*don 7 mysql node.js

nodejs-mysql最近在node.js中使用模块进行查询,在我的工作情况下,我只能使用参数绑定语法,如:

SELECT * FROM table WHERE name = ?
Run Code Online (Sandbox Code Playgroud)

现在我想用这些?OR ??参数构建动态sql .假设我有两个条件(nameage),其中任何一个都可以为null(如果用户不提供它),所以我想在3种情况下构建MySQL:

  1. name=Bob:SELECT * FROM table WHERE name = 'Bob'
  2. age=40:SELECT * FROM table WHERE age > 40
  3. 都: SELECT * FROM table WHERE name = 'Bob' AND age > 40

我知道如果你自己构建查询很容易,但是在使用只能绑定字段或值的占位符时如何实现呢?

在文档中nodejs-mysql,占位符?仅代表值并??代表字段:

我的解决办法首先的想法是通过使用这些占位符插入查询一块,但它涉及到失败的,因为这两个???将难逃我的查询片,我的查询将被正确执行.

到目前为止,我的代码如下所示,我确定它不正确,因为查询件已被转义:

// achieve paramters from url request
var condition = {};
if(params.name)condition["name"] = ["LIKE", "%" + params.name + "%"];
if(params.age)condition["age"] = parseInt(params.age, 10);

//build query
var sqlPiece = buildQuery(condition);

//try to replace ? with query
var sql = 'SELECT * FROM table WHERE ?';

connection.query(sql, sqlPiece, function(err, results) {
  // do things
});

// my own query build function to proceed conditions
function buildQuery(condition) {
  var conditionArray = [];
  for(var field in condition){
    var con = condition[field];
    if(con !== undefined){
      field = arguments[1] ? arguments[1] + "." + field : field;
      var subCondition;
      if(con instanceof Array) {
        subCondition = field + " " + con[0] + " " + wrapString(con[1]);
      }else{
        subCondition = field + " = " + wrapString(con);
      }
      conditionArray.push(subCondition);
    }
  }
  return conditionArray.length > 0 ? conditionArray.join(" AND ") : "1";
}

//wrap string value
function wrapString(value){
  return typeof value === "string" ? "'" + value + "'" : value;
}
Run Code Online (Sandbox Code Playgroud)

那么有什么方法可以解决这个问题吗?

更新

感谢Jordan的优惠,它正在发挥作用,但是:

我知道通过字符串连接建立查询是非常好的,但在我的情况下我不能使用它,因为我使用一些中间件或处理mysql和控制器,所以我能做的是定义接口,这是一个sql字符串与占位符.因此,接口字符串之前是预定义的,在控制器功能期间我无法修改它.

Jor*_*ing 15

你有一个非常好的开始,但你可能已经过度思考了一下.诀窍是使用占位符(?)作为字符串构建查询,同时构建一个值数组.

所以,如果你有params = { name: 'foo', age: 40 },你想要构建以下对象:

where = 'name LIKE ? AND age = ?';
values = [ '%foo%', 40 ];
Run Code Online (Sandbox Code Playgroud)

如果你只有{ name: 'foo' },那么你将构建这些:

where = 'name LIKE ?';
values = [ '%foo%' ];
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,您都可以直接在query方法中使用这些对象,即:

var sql = 'SELECT * FROM table WHERE ' + where;
connection.query(sql, values, function...);
Run Code Online (Sandbox Code Playgroud)

那么我们如何构建这些对象呢?实际上,代码与您的buildQuery功能非常相似,但不太复杂.

function buildConditions(params) {
  var conditions = [];
  var values = [];
  var conditionsStr;

  if (typeof params.name !== 'undefined') {
    conditions.push("name LIKE ?");
    values.push("%" + params.name + "%");
  }

  if (typeof params.age !== 'undefined') {
    conditions.push("age = ?");
    values.push(parseInt(params.age));
  }

  return {
    where: conditions.length ?
             conditions.join(' AND ') : '1',
    values: values
  };
}

var conditions = buildConditions(params);
var sql = 'SELECT * FROM table WHERE ' + conditions.where;

connection.query(sql, conditions.values, function(err, results) {
  // do things
});
Run Code Online (Sandbox Code Playgroud)