执行触发器时,精确获取返回的行数超过请求的行数 SQL*PLUS
Posted
技术标签:
【中文标题】执行触发器时,精确获取返回的行数超过请求的行数 SQL*PLUS【英文标题】:exact fetch returns more than request number of rows when trigger is executed SQL*PLUS 【发布时间】:2013-12-08 18:00:44 【问题描述】:我需要将触发器合并到我的一个使用光标的脚本中。所以我有一个带有光标的脚本,以及一个创建触发器的脚本(称为'trigEmpRaise')。触发器的创建没有错误,但是当我使用光标运行脚本(在创建触发器之前运行良好)时,我得到了这些错误:
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SCOTT.TRIGEMPRAISE", line 8
ORA-04088: error during execution of trigger 'SCOTT.TRIGEMPRAISE'
ORA-06512: at line 34
以下是表格的说明:
SQL> describe empcopy
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
SQL> describe emp_prob1;
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NUMBER(4)
ENAME VARCHAR2(10)
DEPTNO NUMBER(2)
SAL NUMBER(7,2)
SQL> describe empraises;
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NUMBER(4)
ENAME VARCHAR2(15)
SAL NUMBER(7,2)
DATEOF DATE
以下是脚本: 带有光标的脚本(触发触发器)
SET SERVEROUTPUT ON
DECLARE
vEMPNO empcopy.empno%TYPE;
VENAME empcopy.ename%TYPE;
vDEPTNO empcopy.deptno%TYPE;
vSAL empcopy.sal%TYPE;
CURSOR deptnoCUR IS
SELECT empno, ename, deptno, sal
FROM empcopy
ORDER BY deptno;
FUNCTION calcSal
(fDEPTNO varchar2, fSAL number)
RETURN NUMBER IS
fNewSal empcopy.sal%TYPE;
BEGIN
IF fDEPTNO = 10 THEN
fNewSal := fSAL + fSAL * .05;
ELSE
IF fDEPTNO = 20 THEN
fNewSal := fSAL + fSAL * .075;
ELSE
fNewSal := fSAL + fSAL * .10;
END IF;
END IF;
RETURN fNewSal;
END calcSal;
BEGIN
OPEN deptnoCUR;
LOOP
FETCH deptnoCUR INTO vEMPNO, vENAME, VDEPTNO, vSAL;
EXIT WHEN deptnoCUR%NOTFOUND;
vSAL := calcSal(vDEPTNO,vSAL);
INSERT INTO emp_prob1
VALUES(vEMPNO,vENAME,vDEPTNO,vSAL);
END LOOP;
CLOSE deptnoCUR;
END;
/
SET SERVEROUTPUT OFF
SELECT * FROM emp_prob1;
和触发脚本:
CREATE OR REPLACE TRIGGER trigEmpRaise
AFTER INSERT ON emp_prob1
DECLARE
vEMPNO empraises.empno%TYPE;
vENAME empraises.ename%TYPE;
vSAL empraises.sal%TYPE;
vDATE empraises.dateof%TYPE := sysdate;
BEGIN
SELECT empno, ename, sal
INTO vEMPNO, vENAME, vSAL
FROM emp_prob1;
INSERT INTO empraises (empno,ename,sal,dateof)
VALUES(vEMPNO,vENAME,vSAL,vDATE);
END;
/
带有光标的脚本会简单地遍历表 EMPCOPY 中的每条记录,并根据它们所在的 DEPTNO 对它们进行提升。然后它将新值插入到表 EMP_PROB1 中。
触发器应该在将值插入到 EMP_PROB1 之后发生,并将新的薪水和插入发生的系统日期放入表 EMRAISES。
但是,无论我做什么,上述错误都会不断发生。有什么帮助吗?
【问题讨论】:
【参考方案1】:SELECT empno, ename, sal
INTO vEMPNO, vENAME, vSAL
FROM emp_prob1;
必须准确返回 1 行 - 不多也不少。
我的假设是你喜欢这样做:
CREATE OR REPLACE TRIGGER trigEmpRaise
AFTER INSERT ON emp_prob1
FOR EACH ROW
BEGIN
INSERT INTO empraises (empno,ename,sal,dateof)
VALUES(:new.empno,:new.ename,:new.sal,sysdate);
END;
/
【讨论】:
好的,但我不确定为什么它不只返回 1 行。我做错了什么? @DavidLacombe 每次执行函数时,您都会将值插入到emp_prob1
中,并且触发器内的SELECT
-statement 不受任何WHERE
-条件的约束,因此您基本上选择了所有多个条目以上是关于执行触发器时,精确获取返回的行数超过请求的行数 SQL*PLUS的主要内容,如果未能解决你的问题,请参考以下文章
获取 ORA-01422 的原因:精确提取返回的行数超过了请求的行数
当我已经使用游标时,为啥我得到“精确提取返回的行数超过请求的行数”?
尝试从两列中提取多条记录时,精确提取返回的行数超过了请求的行数