1

如果当时表中只有一个电话号码,我想防止删除电话号码。

到目前为止,我有这个触发器:

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 自治事务。这会导致故障,我想尽可能避免它。

  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;

这也不起作用。

有什么方法可以轻松解决这个问题吗?谢谢!

4

1 回答 1

2

这应该被认为是伪代码

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;

触发器隐藏了您的业务逻辑。通过拥有一个只做一件事且只做一件事的函数,你可以让下一个查看你工作的程序员清楚地知道你想要什么。

于 2020-03-18T13:17:38.497 回答