БД Oracle, изменение количества запасов по сделке - PullRequest
0 голосов
/ 14 декабря 2018

Я работаю над некоторыми функциями для проекта, использующего Oracle.У меня есть две таблицы, Inventory и Transaction, где в таблице Inventory есть ряды элементов, каждая из которых имеет ID и Count, например: ID = 'ProductA' Count = 12

Transaction таблица содержит строки транзакций, имеющие TXID, ItemID, ItemQuantity, например: TXID = '00012', ItemID = 'ProductA', ItemQuantity = 5

Мне нужно иметь возможность обновлять количество элементов в Inventory при новой транзакциисделан.

Я мог бы сделать это с несколькими операторами,

INSERT INTO "TRANSACTION"
(TRANSACTIONID ....
VALUES('00012' .....`

UPDATE INVENTORY
SET  Count = Count - ItemQuantity
WHERE ROWID='ProductA'

`

Но это не кажется правильным, что если есть какая-то ошибка и не все операторы выполняются.

Какой формат я должен использовать для этого типа функций?

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Вы ищете триггер после вставки в таблицу Transaction, который обновляет таблицу Inventory.

С этим решением вам не нужно выполнять 2 оператора(1 достаточно).Кроме того, вы легко получаете атомарную транзакцию , поскольку концептуально изменения, сделанные в триггере, относятся к той же транзакции, что и операция, которая ее сгенерировала.

Способ работы:

  • Oracle запускает триггер после каждой успешной операции INSERT на Transaction

  • Внутри триггера у вас есть доступ к значениям, которые были только что вставлены вTransaction с использованием префикса :NEW;эти значения используются для обновления Inventory

Код:

CREATE OR REPLACE TRIGGER update_inventory_after_transaction
AFTER INSERT ON transaction
FOR EACH ROW
BEGIN
    UPDATE inventory SET Count = Count - :NEW.ItemQuantity WHERE ROWID = :NEW.ID;
END;
/

Относительно управления транзакциями согласно Документация Oracle :

... если триггер выполняет инструкцию, которая вызывает исключение, и исключение не обрабатывается обработчиком исключения, то база данных откатывает эффекты как триггера, так и его оператора триггера.

После создания триггера, это происходит каждый раз при выполнении операции INSERT на Transaction:

  • , если при вставке транзакции возникает ошибка, триггерне срабатывает
  • , если транзакция успешно вставлена, обновление инвентаризации запускается
  • , если триггер не работает, вставленные транзакции автоматически откатываются
  • , если все проходит гладко, тогдаможно смело звонить COMMIT
0 голосов
/ 14 декабря 2018

Звучит так, как будто вы хотите использовать SQL «транзакции» .

Например:

-- In Oracle, this begins an implicit transaction
INSERT INTO "TRANSACTION"(TRANSACTIONID ....) VALUES('00012 .....)
UPDATE INVENTORY SET  Count = Count - ItemQuantity WHERE ROWID='ProductA'
COMMIT

Чтобы это работало, вам понадобится«ItemQuantity» как некоторая переменная.Я полагаю, что вы читаете его из PHP: вы можете начать с использования переменной PHP.

Еще лучше рассмотреть возможность использования Подготовленные операторы и / или Хранимые процедуры .

Вы можете также рассмотреть возможность настройки «TRANSACTIONID» как Столбец идентификации .

Дополнительная информация:

Транзакция - это логическая элементарная единица работы, которая содержит один или несколько операторов SQL.

Транзакция группирует операторы SQL так, чтобы они были либовсе зафиксировано, что означает, что они применены к базе данных, или все откатано, что означает, что они отменены из базы данных.Oracle Database присваивает каждой транзакции уникальный идентификатор, называемый идентификатором транзакции.

Все транзакции Oracle подчиняются основным свойствам транзакции базы данных, известной как свойства ACID

Транзакция начинается с первого исполняемого оператора SQL.Транзакция заканчивается, когда она фиксируется или откатывается, либо явно с помощью оператора COMMIT или ROLLBACK, либо неявно, когда выполняется оператор DDL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...