Как обновить строку на основе изменений в другой строке? - PullRequest
1 голос
/ 11 мая 2019

Скажем, у меня есть две таблицы для отслеживания банковского счета:

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?

Ответы [ 2 ]

1 голос
/ 12 мая 2019

Это типичный вариант использования триггера. Надеюсь, этот пример поможет.

-- 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         */
1 голос
/ 11 мая 2019

В комнате есть все инструменты, необходимые для этого:

Использование LiveData с комнатой

Библиотека постоянства Room поддерживает наблюдаемые запросы, которые возвращают объекты LiveData. Наблюдаемые запросы записываются как часть объекта доступа к базе данных (DAO).

Room генерирует весь необходимый код для обновления объекта LiveData при обновлении базы данных. Сгенерированный код выполняет запрос асинхронно в фоновом потоке, когда это необходимо. Этот шаблон полезен для синхронизации данных, отображаемых в пользовательском интерфейсе, с данными, хранящимися в базе данных. Вы можете прочитать больше о Room и DAO в постоянном библиотечном руководстве для Room.

Просто посмотрите на LiveData, возвращенный вами @Query in Room, и вы можете выполнить дополнительную логику с возвращенным результатом.

...