在触发器中编译if else条件时的错误

时间:2014-02-12 04:01:51

标签: oracle hibernate

 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 ;

我正在尝试检查重复输入。如果不存在,那么我将从序列创建一个新的Id。否则我会使用相同的ID。   而SaveOrUpdate(dept);将完成余下的工作。

但它给了我编译错误。Error(8,9): PL/SQL: SQL Statement ignored.

UPDATE:

当我尝试以下查询时:

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;

获取错误:

ORA-01422: exact fetch returns more than requested number of rows

如何处理此错误?

2 个答案:

答案 0 :(得分:0)

您可以像这样编写触发器,

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;

<强>编辑:

如果表格中有重复的条目,您可以按如下方式修改触发器代码。

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;

答案 1 :(得分:0)

尝试在where部分添加rownum

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;

这将使查询只返回1行,以防cd.st_num和cd.td_NUMBER在多行中重复。

另一方面,如果您需要检测这两列有多行,则可以在例外部分中捕获异常TOO_MANY_ROWS

     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;