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.
当我尝试以下查询时:
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
如何处理此错误?
答案 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;