Запрет удаления из таблицы, если только одна запись - PullRequest
1 голос
/ 18 марта 2020

Я хочу предотвратить удаление номера телефона, если в данный момент в таблице только один номер.

Пока у меня есть этот триггер:

CREATE OR REPLACE TRIGGER T_TfnoCliente_Cliente
BEFORE DELETE ON TFNO_CLIENTE
FOR EACH ROW
DECLARE
--PRAGMA AUTONOMOUS_TRANSACTION;
telefonosClienteAtencion NUMBER;
BEGIN
telefonosClienteAtencion := 0;
SELECT count(1) INTO telefonosClienteAtencion FROM TFNO_CLIENTE WHERE id = :old.id AND tipo = :old.tipo;
IF telefonosClienteAtencion < 2 THEN
  RAISE_APPLICATION_ERROR(-20101, 'Cannot delete a phone number if the user doesn't have more than one phone associated');
END IF;
END;

Я получаю ошибку ORA-04091: таблица TFNO_CLIENT мутирует (...)

Я понимаю проблему , и я попробовал несколько альтернатив:

  1. Pragma autpendent_transaction. Это вызывает сбои в работе, и я хотел бы избежать этого в максимально возможной степени.

  2. Вместо запроса самой таблицы, запрос представления, содержащего счет:

Затем я изменил запрос на

SELECT no_tfnos INTO telefonosClienteAtencion FROM CLIENTES_TFNOS WHERE cliente = :old.id;

CREATE OR REPLACE VIEW CLIENTES_TFNOS (cliente, no_tfnos) AS
SELECT id, count(*) 
from TFNO_CLIENTE 
group by id;

Это тоже не сработало.

Есть ли способ решить эту проблему легко? Спасибо!

1 Ответ

2 голосов
/ 18 марта 2020

Это следует считать псевдокодом

FUNCTION FN_HasMoreThanOnePhoneNumber(vclient_id IN NUMBER, vphone IN VARCHAR2) 
RETURN BOOLEAN IS
telefonosClienteAtencion NUMBER;
vResult BOOLEAN := FALSE;
BEGIN
telefonosClienteAtencion := 0;
SELECT count(*) 
INTO telefonosClienteAtencion 
FROM TFNO_CLIENTE WHERE id = vclient_id 
AND tipo = vphone;

IF telefonosClienteAtencion > 1 THEN
  vResult := TRUE;
END IF;

RETURN vResult;

END FN_HasMoreThanOnePhoneNumber;

Тогда в вашем коде, где вы принимаете решение вставить или удалить его, может работать следующим образом

IF FN_HasMoreThanOnePhoneNumber(lclientId, lPhone) THEN
   process new data by deleting old phone number
ELSE
   RAISE_APPLICATION_ERROR(-20101, 'Cannot delete a phone number if the user doesn't have 
   more than one phone associated');
END IF;

Триггер скрывает ваш бизнес логи c. Имея функцию, которая выполняет одну и только одну вещь, вы можете донести то, что хотите, до следующего программиста, который смотрит на вашу работу.

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