【问题标题】:how to add items in a database for billing systems如何在计费系统的数据库中添加项目
【发布时间】:2019-03-05 07:28:21
【问题描述】:

我正在开发一个基于云的计费系统,我的数据库中有两个表,即bill_historysold_items。我想存储账单编号、日期、客户姓名、电话号码和总金额,然后从bill_history 返回账单编号,并存储包含项目编号、项目名称、价格、数量、金额的对象数组以及返回的sold_items 中的账单号。我正在使用以下代码:

app.post('/billed', (req, res) => {
    const { items, total, date } = req.body;
    console.log(items, total, date);

    db.transaction(trx => {
        db.insert({
            total: total,
            date: date,
          }).into('billhead')
          .transacting(trx)
          .returning('billno')
          .then(num => {
              for (var i = 0; i < items.length; i++) {
                trx.insert({
                  billno: num,
                  prodname: items[i].name,
                  quantity: items[i].quantity,
                  netprice: items[i].amount
                }).into('billdetails')
              }).then(trx.commit())
            .catch(trx.rollback())
          })
    })

现在在bill_history 中找到条目,但在sold_items 中没有输入。我找不到错误!帮我解决这个错误。控制台和终端显示没有错误

【问题讨论】:

  • 欢迎来到 StackOverflow!分享您的研究对每个人都有帮助。告诉我们您尝试了什么以及为什么它不能满足您的需求。这表明您已经花时间尝试帮助自己,它使我们免于重复明显的答案,最重要的是它可以帮助您获得更具体和相关的答案!另见:How to Ask

标签: javascript node.js postgresql transactions knex.js


【解决方案1】:

在使用 knex 查询时要记住的重要一点:它们是 promises,它们只会在以下情况下执行:

  1. 您在 knex 对象本身上调用 then
  2. 返回承诺链中的 knex 查询,然后在链的下游某处调用 then

for 循环中,您只说明了 knex 对象应该做什么,并且由于语法错误没有调用 knex 对象本身

.into('billdetails').then(inserts => { /// })

如果你 return trx.insert()...

它确实有效

话虽如此,它不适合您的用例,因为在事务中插入多个值时,您需要确保所有插入都已成功。以异步方式使用 for 循环是危险的,并且不能保证所有单独的插入都已完成且没有错误,并且提交事务是安全的。

以安全的方式实现此目的的一种方法是修改代码的这一部分:

// ...
    .returning('billno')
    .then(num => {
            // We create an array of individual inserts
            // Each element in the array will be a single knex 
            // object/promise that inserts one row into the database 
            const billDetailInserts = items.map(item => trx.insert({
                    billno: num,
                    prodname: item.name,
                    quantity: item.quantity,
                    netprice: item.amount
                ).into('billdetails')
            })

            // we utilize the Promise.all method that will resolve when
            // all individual inserts have completed succesfully
            return Promise.all(billDetailInserts);
        })
    .then(inserts => {
    // ... commits, rollbacks, logging etc

【讨论】:

    猜你喜欢
    • 2012-02-12
    • 2014-05-17
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    相关资源
    最近更新 更多