【问题标题】:Express/node-postgres pass an object with multiple values to insert queryExpress/node-postgres 传递具有多个值的对象以插入查询
【发布时间】:2017-07-25 14:11:06
【问题描述】:

我正在序列化表单并使用 jQuery AJAX 将数据发送到快速路由:

发送为arrobj的对象例如:

{ 
  col1: [ 'one', 'two', 'three' ],
  col2: [ 'foo', 'bar', 'baz' ]
}

在路由中,我有一个创建参数化查询字符串的函数,如下所示:

function create_insert_SQL(obj, table, returnid) {
    // Loop through OBJ and extract column names
    var cols = ''; // Store column names
    var params = ''; // Store Parameter references eg. $1, $2 etc
    var count = 1;
    for(var p in obj) {
        cols += p + ",";
        params += "$" + count + ",";
        count++;
    };
    var strSQL = "INSERT INTO " + table + " (";
    strSQL += cols.substr(0, cols.length - 1);
    strSQL += ') VALUES (';
    strSQL += params.substr(0, params.length - 1)
    strSQL += ') returning ' + returnid + ' as id';
    return strSQL;
}

这将返回insert into mytable (col1,col2) values ($1, $2);

创建查询字符串后,我在传递对象的 node-postgres 中运行插入查询:

db.query(SQL, arrobj, function (err, result) {
    if (err) {
        res.send(err)
    } else {
        res.send(result.rows[0].id.toString()) // return the inserted value
    }
});

对于每个键中的单个值,一切正常,并且数据正确插入到表中。

如何使插入查询针对键的每个值运行?

例子:

insert into table (col1, col2) values ('one', 'foo');
insert into table (col1, col2) values ('two', 'bar');
insert into table (col1, col2) values ('three', 'baz');

【问题讨论】:

标签: node.js express node-postgres


【解决方案1】:

第一个也是最棘手的部分是反转对象结构,以便插入行。请查看下面的 sn-p 并运行它以查看会发生什么。

之后,您可以遍历列(对于.. in,就像您已经拥有的那样)以获取 INSERT INTO 列部分,并遍历新对象的行以获取值部分。这应该很容易,如果您需要帮助,请告诉我。

var obj = { 
  col1: [ 'one', 'two', 'three' ],
  col2: [ 'foo', 'bar', 'baz' ],
  col3: [ '1', '2', '3' ]
}

//console.log(obj);

var invert = function (obj) {

  var new_obj = [];
  
  // iterate over props
  for (var prop in obj) {
    // iterate over columns
    for(var i=0;i<obj[prop].length;i++) {
    // if a row exists, assign value to it
     if (new_obj[i]) {
      new_obj[i][prop] = obj[prop][i];
     } else {
     // if it doesn't, create it
      var row = {};
      row[prop] = obj[prop][i];
      new_obj.push(row);
     }
    }
  }

  return new_obj;
};

var bulkStatement = function (table, rows) {
  var params = [];
  var chunks = [];
  var statement = 'INSERT INTO ' + table + '(';
  
  for (var prop in rows[0]) {
    statement += prop + ',';
  }
  
  statement = statement.slice(0,-1) + ') VALUES ';
  
  for(var i = 0; i < rows.length; i++) {
    var row = rows[i];
    var valueClause = [];
    for (var prop in row) {
      params.push(row[prop]);
      valueClause.push('$' + params.length);
    }
    chunks.push('(' + valueClause.join(', ') + ')');
  }

  return {
    text: statement + chunks.join(', '),
    values: params
  }
};

var inverted = invert(obj);

console.log(bulkStatement('tableName', inverted));

【讨论】:

  • 是的,这就是要走的路。唯一的问题是它为新对象的键分配了一个序列值,而不是原始对象的名称。例如 0,1,2 而不是 col1, col2
  • 我也添加了SQL生成功能,请看编辑
  • @FabrizioMazzoni 你能做到吗?
猜你喜欢
  • 1970-01-01
  • 2015-05-19
  • 2017-08-01
  • 2011-09-15
  • 2021-03-05
  • 2017-07-31
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多