Oracle 触发器中if-else条件的编译错误

Oracle 触发器中if-else条件的编译错误,oracle,hibernate,Oracle,Hibernate,我正在检查是否有重复条目。如果不存在,那么我将从序列创建一个新Id。否则我会把相同的id。 以及SaveOrUpdate(dept)将执行剩余的操作 但它给了我编译错误。error(8,9):PL/SQL:SQL语句被忽略。 更新: 当我尝试以下查询时: create or replace TRIGGER TRG_DEPT_ID BEFORE INSERT ON DEPT FOR EACH ROW BEGIN IF NOT EXISTS (SELECT * FROM DEPT cd

我正在检查是否有重复条目。如果不存在,那么我将从序列创建一个新Id。否则我会把相同的id。 以及
SaveOrUpdate(dept)将执行剩余的操作

但它给了我编译错误。
error(8,9):PL/SQL:SQL语句被忽略。

更新: 当我尝试以下查询时:

 create or replace
  TRIGGER TRG_DEPT_ID BEFORE INSERT ON DEPT FOR EACH ROW
  BEGIN
  IF NOT EXISTS (SELECT * FROM DEPT cd WHERE cd.st_num = :new.ST_NUMBER AND cd.td_NUMBER = :new.TD_NUMBER)
  THEN
        SELECT SEQ_DEPT_ID.NEXTVAL INTO :new.ID FROM dual;        
  ELSE
        SELECT ID FROM DEPT INTO :new.ID WHERE cd.st_num = :new.ST_NUMBER AND cd.td_NUMBER = :new.TD_NUMBER;
  END IF;   
  END ;
获取错误:

ORA-01422:exact fetch返回的行数超过请求的行数


如何处理此错误?

您只需像这样编写触发器代码

CREATE OR REPLACE TRIGGER TRG_DEPT_ID 
BEFORE INSERT ON DEPT FOR EACH ROW
BEGIN
     BEGIN
          SELECT ID 
          INTO :NEW.ID 
          FROM DEPT 
          WHERE cd.st_num = :NEW.ST_NUMBER 
          AND cd.td_NUMBER = :NEW.TD_NUMBER;     
     EXCEPTION WHEN no_data_found THEN
          SELECT SEQ_DEPT_ID.NEXTVAL INTO :new.ID FROM dual;        
     END;
END;
编辑:

如果表中存在重复条目,则可以按如下所示修改触发器代码

CREATE OR REPLACE TRIGGER TRG_DEPT_ID 
BEFORE INSERT ON DEPT FOR EACH ROW
BEGIN
     BEGIN
          SELECT ID 
          INTO :NEW.ID 
          FROM DEPT 
          WHERE cd.st_num = :NEW.ST_NUMBER 
          AND cd.td_NUMBER = :NEW.TD_NUMBER
          AND rownum = 1;    --Use rownum = 1 to avoid selecting too many rows.
     EXCEPTION WHEN no_data_found THEN
          SELECT SEQ_DEPT_ID.NEXTVAL INTO :new.ID FROM dual;
          --:NEW.id = seq_dept_id.nextval; -- Or you can use this if you are using 11g or higher versions.
     END;
END;

尝试在where部分添加
rownum

CREATE OR REPLACE TRIGGER TRG_DEPT_ID 
BEFORE INSERT ON DEPT FOR EACH ROW
DECLARE 
     l_id DEPT.id%type;
BEGIN
     BEGIN
          SELECT ID 
          INTO l_id
          FROM DEPT 
          WHERE cd.st_num = :NEW.ST_NUMBER 
          AND cd.td_NUMBER = :NEW.TD_NUMBER
          AND ROWNUM = 1;    --Use rownum = 1 to avoid selecting too many rows.
          IF l_id IS NOT NULL THEN --If same st_number and td_number exists.
               raise_application_error( -20001, 'Duplicate entry.');
          END IF;
     EXCEPTION WHEN no_data_found THEN
          SELECT SEQ_DEPT_ID.NEXTVAL INTO :new.ID FROM dual;
          --:NEW.id = seq_dept_id.nextval; -- Or you can use this if you are using 11g or higher versions.
     END;
END;
如果cd.st_num和cd.td_NUMBER在多行中重复,那么查询将只返回1行

另一方面,如果需要检测这两列有多行,可以在exceptions部分捕获异常
太多行

CREATE OR REPLACE TRIGGER TRG_DEPT_ID 
BEFORE INSERT ON DEPT FOR EACH ROW
BEGIN
    BEGIN
       SELECT ID 
       INTO :NEW.ID 
       FROM DEPT 
       WHERE cd.st_num = :NEW.ST_NUMBER 
       AND cd.td_NUMBER = :NEW.TD_NUMBER
       AND ROWNUM =1;   
 EXCEPTION WHEN no_data_found THEN
      SELECT SEQ_DEPT_ID.NEXTVAL INTO :new.ID FROM dual;        
 END;
END;

那么,您的查询将返回多行。您的约束错误,或者如果允许多行,则需要更改逻辑。@OldProgrammer:是。。如果我使用rownum来解决上述问题,则将发生唯一密钥冲突。请尝试此操作。这次
ORA-00001:unique constraint(DEPT_PK)违反了DEPT表中的主键列
@tailorBird。只有列
ID
@tailorBird,所以听起来DEPT表中的max(ID)超出了SEQ_DEPT_ID.nextval的值。所以你们需要比较两者并重新创建你们的序列。序列最后的编号是161,表格只有一行id=141。
     EXCEPTION WHEN no_data_found THEN
      SELECT SEQ_DEPT_ID.NEXTVAL INTO :new.ID FROM dual;        
     when TOO_MANY_ROWS then
         -- your logic to do when there are too many rows     
 END;