【问题标题】:Inserting multiple rows with multiple columns in Node and sqlite3在Node和sqlite3中插入多行多列
【发布时间】:2019-05-19 18:40:27
【问题描述】:

我正在尝试使用单个操作将许多不同的行插入到 sqlite 数据库中。每行都有多列,我将数据表示为数组。

我已阅读用户指南和其他教程,但所有提到插入多行的教程都适用于只有一列的行。

我正在尝试插入一个更大的数组,但为了测试它,我将它分成两个条目。

let testArtist = [["string", 1, 2, "string"], ["string", 3, 4, "string"]];
let artistQuery = "INSERT INTO artists (artist, numSongs, numAlbums, picture) VALUES (?, ?, ?, ?), (?, ?, ?, ?)";

db.serialize(
    db.run(artistQuery, [testArtist], function(err){
        if(err) throw err;
    });
});

这是插入操作的结果

select * from artists;
1||||
2||||

所以AUTOINCREMENT整数ID被插入,但数据没有。

【问题讨论】:

    标签: node.js sqlite node-sqlite3


    【解决方案1】:

    我想@Chris 自己的回答是在一个巨大的 INSERT 语句中完成多行和多列的唯一方法(尽管我很想知道为什么它只需要一个操作)。

    我也很难在 node.js 中找到 sqlite3 的示例(这就是我在这里结束的方式)所以我想分享一个实现上述目标但具有多个操作的多列示例。

    let testArtist = [
       ["string", 1, 2, "string"],
       ["string", 3, 4, "string"]
    ];
    
    // create the statement for the insertion of just ONE record
    let artistQuery = 
       "INSERT INTO artists (artist, numSongs, numAlbums, picture) " +
       "VALUES (?, ?, ? ,?)"; 
    
    // 'prepare' returns a 'statement' object which allows us to 
    // bind the same query to different parameters each time we run it
    let statement = db.prepare(artistQuery);
    
    // run the query over and over for each inner array
    for (var i = 0; i < testArtist.length; i++) {
        statement.run(testArtist[i], function (err) { 
            if (err) throw err;
        });
    }
    
    // 'finalize' basically kills our ability to call .run(...) on the 'statement'
    // object again. Optional.
    statement.finalize();
    
    // If I call statement.run( ... ) here again, I will get an error due 
    // to the 'finalize' call above.
    

    如果您需要保证所有行都按顺序插入,您可以像@Chris 那样将整个循环包装在db.serialize( ... ) 中。

    【讨论】:

      【解决方案2】:

      编辑:伙计们,我自己想通了。您需要做的是将数组展平为单个数组。

      所以: [["string", 1, 2, "string"], ["string", 3, 4, "string"]]

      变成: ["string, 1, 2, "string", "string", 3, 4, "string"]

      您仍然需要分隔 INSERT INTO 操作中的值,我为此使用了 map 函数,如教程中所述。

      let artistPlaceholders = artistRecords.map(() => "(?, ?, ?, ?)").join(', ');
      let artistQuery = "INSERT INTO artists (artist, numSongs, numAlbums, picture) VALUES " + artistPlaceholders;
      let flatArtist = [];
      artistRecords.forEach((arr) => { arr.forEach((item) => { flatArtist.push(item) }) });
      
      db.serialize(function(){
          db.run(artistQuery, flatArtist, function(err){
              if(err) throw err;
          });
      });
      

      其中artistRecords 是一个数组,格式为:

      [["string", 0, 0, "string"], ["string", 0, 0, "string"], [...]]
      

      如果您有一个具有多层嵌套的数组,则需要修改展平功能。

      【讨论】:

      • 这对我来说很棒,我更喜欢 100 行的插入作为 100 行的插入。顺便说一句,您可以使用 .flat() 方法来展平数组。
      猜你喜欢
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多