Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL触发器电子邮件唯一_Sql_Oracle_Triggers - Fatal编程技术网

SQL触发器电子邮件唯一

SQL触发器电子邮件唯一,sql,oracle,triggers,Sql,Oracle,Triggers,我想创建一个触发器,而不是一个约束来验证电子邮件是否已经存在。如果是,触发器将引发错误。如果没有,则将电子邮件插入表中 我从这个开始,但它不起作用: CREATE OR REPLACE TRIGGER TRIGGER3 BEFORE INSERT ON FV_CLIENT FOR EACH ROW BEGIN IF EXISTS (SELECT COURRIEL FROM FV_CLIENT WHERE COURRIEL=:new.courriel)

我想创建一个触发器,而不是一个约束来验证电子邮件是否已经存在。如果是,触发器将引发错误。如果没有,则将电子邮件插入表中

我从这个开始,但它不起作用:

CREATE OR REPLACE TRIGGER TRIGGER3 
       BEFORE INSERT ON FV_CLIENT FOR EACH ROW
BEGIN
  IF EXISTS (SELECT COURRIEL FROM FV_CLIENT
            WHERE COURRIEL=:new.courriel) THEN

     raise_application_error(-20001,'Courriel deja existant, choisir une autre combinaison courriel/Mot de passe');          
  END IF;
END;
由于命令raise\u application\u出错,我猜这是一个ORACLE数据库。假设您有这个表:

CREATE TABLE FV_CLIENT (
   COURRIEL VARCHAR2(48)
);
您可以使用此触发器:

CREATE OR REPLACE TRIGGER TRIGGER3 
BEFORE INSERT ON FV_CLIENT FOR EACH ROW
DECLARE
  CURSOR check_curriel IS
  SELECT 1
    FROM FV_CLIENT 
   WHERE COURRIEL = :new.COURRIEL;
   x VARCHAR2(48);
BEGIN
  OPEN check_curriel;
  FETCH check_curriel INTO x;
  IF NOT check_curriel%NOTFOUND THEN
    CLOSE check_curriel;
    raise_application_error(-20001,'Courriel deja existant, choisir une autre combinaison courriel/Mot de passe');
  END IF;
  CLOSE check_curriel;
END;
前两次插入没有错误:

INSERT INTO FV_CLIENT VALUES ('mon.pere@paris.fr');
INSERT INTO FV_CLIENT VALUES ('mon.frere@lyon.fr');
第三次插入按预期引发异常:

INSERT INTO FV_CLIENT VALUES ('mon.pere@paris.fr');
Fehlerbericht-SQL Fehler:ORA-20001:Courriel deja existant,choisir 在ORA-06512:at处,联合运输公司/运输公司 SCOTT.TRIGGER3,第11行ORA-04088:执行触发器时出错 “斯科特,触发器3”

p、 s:根据Justin Cave的评论,使用上面的触发器可能会导致表异常发生变化,例如:

INSERT INTO FV_CLIENT 
SELECT COURRIEL 
  FROM FV_CLIENT 
 WHERE COURRIEL = 'mon.pere@paris.fr';
返回

00000-表%s.%s正在变化,触发器/函数可能看不到它 *原因:中引用的触发器或用户定义的plsql函数 此语句试图查看或修改已删除的表 在被修改的声明中。 *操作:重写触发器或函数,使其不读取该表。
因此,通常建议使用唯一约束。谢谢你的留言

您使用的是哪种DBMS?当您可以使用效率更高的声明性约束时,为什么要使用效率更低、更容易出错的触发器?除非这是一个家庭作业问题,否则我不明白你为什么会走这条路。有时,基于触发器的解决方案更受欢迎,因为它能够生成有意义的错误描述并生成不同的错误代码。如果你在表中进行插入选择,此触发器将生成变异表异常。一般来说,特定表上的行级触发器不允许查询定义它们的表。@Justin Cave:好的,你完全正确。你有更好的使用触发器的解决方案吗?基于触发器的解决方案通常需要三个触发器和一个包含主键集合或临时表的包,所以它通常会变得复杂得多;我使用了如下描述的内容: