【问题标题】:How to update a row based on changes in another row?如何根据另一行的更改更新一行?
【发布时间】:2019-05-11 03:09:28
【问题描述】:

假设我有两张表来跟踪银行帐户:

Account:
------------------------------
AccountID| Account Value
------------------------------
| 0      | 1000

Transactions:
------------------------------------------------
TransactionID| Transaction Value| Paying Account
-------------------------------------------------    
| 23         | -50.0            | 0
--------------------------------------------------
| 24         | -5               | 0

TransactionID=24 有更新,新值为 -10。 更新帐户价值以反映这一变化的最佳方法是什么?

我在代码中所做的是

  1. 有人在编辑对话框中单击确定后
  2. 通过添加负值来反转原始交易:
  3. 然后将新的交易价值应用到账户

    AccountDAO acc = mDatabase.AccountDAO().getAccount(0);
    acc.account_value += transaction_id_24.value * -1;
    acc.account_value += transaction_id_24_updated.value;
    mDatabase.AccountDAO().updateAccount(acc);
    

    上面的方法可行,但我觉得上面有更好更自动化的方法。

有没有什么办法让数据库自动检测到某笔交易的值发生了变化,然后更新sqlite/android-room中对应的账户?

【问题讨论】:

    标签: android sqlite android-sqlite android-room


    【解决方案1】:

    Room 内置了您需要的所有工具:

    将 LiveData 与 Room 一起使用

    Room 持久性库支持返回 LiveData 对象的可观察查询。可观察查询是作为数据库访问对象 (DAO) 的一部分编写的。

    Room 会在更新数据库时生成更新 LiveData 对象所需的所有代码。生成的代码在需要时在后台线程上异步运行查询。此模式对于保持 UI 中显示的数据与存储在数据库中的数据同步很有用。您可以在 Room 持久库指南中阅读有关 Room 和 DAO 的更多信息。

    只需在 Room 中观察 @Query 返回的 LiveData,您就可以使用返回的结果执行其他逻辑。

    【讨论】:

      【解决方案2】:

      这是触发器的典型用例。 希望这个例子有所帮助。

      -- Standalone example
      
      DROP TABLE IF EXISTS Account;
      DROP TABLE IF EXISTS Transactions;
      DROP TRIGGER IF EXISTS trans_trigger;
      
      create table Account (
         AccountID      INTEGER PRIMARY KEY AUTOINCREMENT,
         AccountValue   REAL            NOT NULL
      );
      create table Transactions (
         TransactionsID      INTEGER PRIMARY KEY AUTOINCREMENT,
         TransactionValue    REAL  NOT NULL,
         AccountID           INT   NOT NULL
      );
      
      -- Initialize data.
      INSERT INTO ACCOUNT (AccountValue, AccountID) VALUES (1000, 0);
      INSERT INTO Transactions (TransactionsID, TransactionValue, AccountID) VALUES (23, -50, 0);
      INSERT INTO Transactions (TransactionsID, TransactionValue, AccountID) VALUES (24, -5, 0);
      
      CREATE TRIGGER 
          trans_trig 
      AFTER UPDATE OF 
          TransactionValue
      ON 
          Transactions
      BEGIN
          -- Remove old transaction and add new.
          UPDATE Account SET AccountValue = AccountValue - old.TransactionValue;
          UPDATE Account SET AccountValue = AccountValue + new.TransactionValue;
      END;
      
      select * from Account;
      /* AccountID | AccountValue
         0         | 1000         */
      UPDATE Transactions SET TransactionValue = -10 WHERE TransactionsID = 24;
      select * from Account;
      /* AccountID | AccountValue
         0         | 995          */
      UPDATE Transactions SET TransactionValue = 50 WHERE TransactionsID = 24;
      select * from Account;
      /* AccountID | AccountValue
         0         | 1055         */
      

      【讨论】:

        猜你喜欢
        • 2020-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多