Sql 如果只有一个条目,则禁止从表中删除

Sql 如果只有一个条目,则禁止从表中删除,sql,oracle,database-trigger,mutating-table,Sql,Oracle,Database Trigger,Mutating Table,如果表中当时只有一个电话号码,我希望防止删除该电话号码 到目前为止,我有一个触发器: CREATE OR REPLACE TRIGGER T_TfnoCliente_Cliente BEFORE DELETE ON TFNO_CLIENTE FOR EACH ROW DECLARE --PRAGMA AUTONOMOUS_TRANSACTION; telefonosClienteAtencion NUMBER; BEGIN telefonosClienteAtencion := 0; SELEC

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

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

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;
这也没用


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

这应该被视为伪代码

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;

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

最简单的方法可能是将“主”电话号码存储在另一个表中,并使用外键关系。另一种方法是在另一个表中保留电话号码的计数,使用触发器进行更新,然后使用
检查
约束以确保该值永远不为
0
。该代码甚至不会编译。请注意未替换的单引号。是的,我从西班牙语翻译了错误。这不是确切的错误消息@stickybitIt最好不要使用触发器。您必须始终有一个电话号码的业务逻辑可以放在一个过程或包中。@kevinsky您能提供一个例子吗?这个函数什么时候执行?我把它叫在扳机里好吗?我的问题是,我需要在数据库本身中测试它,例如,当我执行delete时instruction@MartaLobo这种方法意味着不使用触发器。当您想要发出删除命令时,可以调用函数。它告诉你是否可以继续。好的,谢谢!所以,当直接执行删除指令时,没有办法阻止删除,对吗?@MartaLobo我想我的答案更多的是从应用程序架构的角度来看的。您有哪些服务或用户可以访问数据库?如果您担心他们可能会从此表中删除,请为他们创建没有该权限的角色。通常,控制访问并强制所有用户和服务访问包和过程以更改表中的数据。因此,数据所在的模式所有者被锁定,没有人可以作为他们登录。其他用户也读过。如果他们想要更新/插入/删除,他们必须调用一个包或过程。
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;