Возник вопрос касаемо SQL (сразу говорю, что я SQL знаю не совсем хорошо).
К примеру, в таблице Касса нужно обновлять данные, которые изменяют в Товарах или Пациентах.
Таблица CashBox и Cashless (одинаковые, только в одну наличная, в другую - безналичная оплата)
CREATE TABLE CashBox(ID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY
KEY, Operation VARCHAR(1000), Income DOUBLE PRECISION, Consumption DOUBLE
PRECISION, Balance DOUBLE PRECISION, DateTime TIMESTAMP);
Сделал внутреннюю таблицу для идентификаторов IntCashBox, IntCashless
CREATE TABLE IntCashBox (ID INTEGER GENERATED BY DEFAULT AS IDENTITY
PRIMARY KEY, SourcePatientID INTEGER NOT NULL, SourceGoodsID INTEGER NOT
NULL, CONSTRAINT fk_SourcePatientID(SourcePatientID) references
Patients(id), CONSTRAINT fk_SourceGoodID references
fk_SourceGoodID(SourceGoodsID));
Таблица (предыдущая версия) до FOREIGN KEY:
CREATE TABLE IntCashBox (ID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY
KEY, SourceID INTEGER, TableName VARCHAR(50));
Вот я думаю, можно ли использовать WHERE в FOREIGN KEY (чтобы указать, из какой таблицы пришли данные) ?
Суть такова: ID могут быть одинаковые в Товарах и Пациентах, а исключить дублирование надо просто сделав пометку, из какой таблицы пришли данные.
Делал триггер (это до FOREIGN KEY), в нем-то можно и без FOREIGN KEY делать все, т.е. триггер для таблиц есть и все работает корректно, т.е. пометка, какая таблица пишется в TableName и в триггере обновление проходит корректно (лишний код убрал):
SELECT SourceID, TableName FROM IntCashBox WHERE SourceID = old.ID into
:intSourceID, :sourceTableName;
--и определялось, где обновлять
UPDATE CashBox
SET Income = new.Amount, Balance = new.Amount - Consumption
WHERE :intSourceID = old.ID AND :sourceTableName = 'Patients';
И вот так определялось:
if (new.PaymentType = 'Наличная оплата') then
BEGIN
INSERT INTO IntCashBox ...
--и собственно определялась таблица и вставлялось/обновлялось
--там были поля SourceID и TableName, по которым и определял
END
ELSE
BEGIN
INSERT INTO Cashless
END
Можно было бы триггер оставить и не использовать FOREIGN KEY, но я вот думаю, при бэкапе и восстановлении базы идентификаторы сбрасываются или нет(если не просто копировать файл базы, да так и не делают)? К примеру, в крайнем случае, если вдруг придется пересоздавать базу(не значит, что придется, просто рассматриваю самые крайние случаи), чтобы ID были корректны, для этого вроде и нужны внешние ключи?
Суть вопроса - можно решать такие вопросы исключительно триггером, или все равно желательно FOREIGN KEY? Вообще в таких случаях внешний ключ обязателен или нет?
Ответ
Таблица CashBox и Cashless (одинаковые, только в одну наличная, в другую - безналичная оплата)
В этом корень всех проблем. Таблица должна быть одна, а в ней - дополнительное поле IS_CASH, где 1 будет означать "наличные", а 0 - "безналичная оплата". После этого все резко упростится.
Комментариев нет:
Отправить комментарий