【问题标题】:in sqlite3 (node package), how to run multiple queries by sequence?在 sqlite3(节点包)中,如何按顺序运行多个查询?
【发布时间】:2021-06-07 01:17:51
【问题描述】:

我正在使用这个包:sqlite3 来操作数据库查询,代码如下:

单个查询很简单:

 var sqlite3 = require('sqlite3').verbose();
 let db = new sqlite3.Database('database.sqlite3');
 let entity_1_name = ''
 db.serialize(function(){
   db.get('select * from table1 where id = 1', function(error, row){
      entity_1_name = row.name
   })
 })
 db.close()

但是如何按顺序执行多个查询呢? (例如,我想运行 query1,然后是 query2,然后是 query3)
就像:

 var sqlite3 = require('sqlite3').verbose();
 let db = new sqlite3.Database('database.sqlite3');
 let entity_1_name = ''
 let entity_2_name = ''
 db.serialize(function(){

   // this is query1
   db.get('select * from table1 where id = 1', [], function(error, row){
      entity_1_name = row.name
   })

   // this is query2
   db.get('select * from table2 where dependency_column_name = ' + entity_1_name, function(error,row){
      // this sql returns null value, because when this query was executed, the variable "entity_1_name" was not determined by query1.
   })

 })


 db.close()

【问题讨论】:

  • 经过相当多的实验,只有将第二个查询放在第一个查询的回调中,我才能让它工作。
  • 是的,很容易进入回调地狱......
  • 看起来很简单。我很惊讶他们没有任何查询方法可以返回 DB 对象以外的东西。我可能会考虑围绕这个包编写一个 async/await 包装器,因为我自己想要那个功能。
  • 是的,如果你有 async/await 工作,请告诉我~谢谢。
  • @Siwei sqlite 将其包装在 TS 中,knex imo 更易于使用

标签: node.js sqlite


【解决方案1】:

https://stackoverflow.com/a/40903302/16140221可以帮到你

他们的解决方案是将每个查询放在一个函数中,然后简单地调用它们。 (这是直接摘自答案的代码,不是我的。)

function db_query1(your_param,...., callback){
  // database operation
   db.run( sql , [param,...] , function(err,rows){
      if(err) // return
      else{
         // get rows with callback
         callback(null, rows);
      }
   });
}

function db_query2(your_param,...., callback){
  // database operation
   db.run( sql , [param,...] , function(err,rows){
      if(err) // return
      else{
         // get rows with callback
         callback(null, rows);
      }
   });
}

然后调用函数

db_query1(....,function(err,result1){
   if(err) ...// return 
   // do the things with result1
   // And then call query2
   db_query2(....,function(err,result2){
      if(err) ...// return 
      // do the things with result1
   });
});

【讨论】:

  • 谢谢,您的解决方案是最后的选择。去还可以,但是很容易掉入“回调地狱”。
【解决方案2】:

好的,最后我用promise + async + await 完成了。

步骤 1。定义一个函数返回new Promise()

      do_query_1(material_name){
        // 1. return this new Promise() 
        return new Promise( (resolve, reject) => {
          let db = this.$database_tool.get_db()
          let that = this
          db.serialize(function(){
            db.get(`select * from table1 where id = 1`, [], function(error, row){
              // 2. this is the point, put anything you want to result to resolve()
              resolve(row.id)
            })
          })
          db.close();

        })
      },

步骤 2。定义一个async函数,调用Step1中定义的方法。


      async do_query_2(){
        let that = this
        // other lines was omitted.
        // HERE , use await to get the result from STEP1. 
        let entity_1_name = await that.get_material_id(row.material_name)

        db.serialize(function(){
          let sql = `'select * from table2 where dependency_column_name = ' + entity_1_name`

          db.run(sql)
        })
        db.close();
      },

第 3 步。以正常方式拨打do_query_2()

do_query_2()

就是这样!

【讨论】:

    猜你喜欢
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2019-08-28
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2023-03-31
    相关资源
    最近更新 更多