如何解决如何修复ORA-01422:-无法提取
我不明白为什么会发生此错误。我已经看到了与他在一起的示例,但是人们并不使用for或fetch循环。据我所知,在这种情况下,提取将在游标的所有输出中循环,逐行查询并避免此错误。
查看代码:
CREATE OR REPLACE TYPE tab_dias IS TABLE OF INTEGER;
CREATE OR REPLACE FUNCTION uf_dias_internado_paciente
(v_cod_paciente IN internacao.COD_PACIENTE%TYPE,v_dt_inicio IN internacao.DT_HORA_ENTradA %TYPE,v_dt_fim IN internacao.DT_HORA_ALTA %TYPE)
RETURN tab_dias
IS
v_dias tab_dias := tab_dias();
CURSOR c_dias IS
SELECT EXTRACT(DAY FROM (i.DT_HORA_ALTA - i.DT_HORA_ENTradA)) AS dias
FROM INTERNACAO i
WHERE i.COD_PACIENTE = v_cod_paciente
AND i.DT_HORA_ENTradA >= v_dt_inicio --13
AND i.DT_HORA_ALTA <= v_dt_fim;
linha_dias c_dias%rOWTYPE;
BEGIN
OPEN c_dias;
LOOP
FETCH c_dias INTO linha_dias;
EXIT WHEN c_dias%NOTFOUND;
v_dias(v_dias.last) := linha_dias.dias;
END LOOP;
CLOSE c_dias;
RETURN v_dias;
END;
错误:ORA-01422: exact fetch returns more than requested number of rows
我正在运行的代码:
SELECT uf_dias_internado_paciente (5007,CURRENT_TIMESTAMP - 500000,CURRENT_TIMESTAMP ) FROM DUAL;
所需的输出:
SELECT (EXTRACT(DAY FROM (i.DT_HORA_ALTA - i.DT_HORA_ENTradA)))
FROM INTERNACAO i
WHERE i.COD_PACIENTE = 5007
AND i.DT_HORA_ENTradA >= CURRENT_TIMESTAMP - 500000
AND i.DT_HORA_ALTA <= CURRENT_TIMESTAMP;
(EXTRACT(DAYFROM(I.DT_HORA_ALTA-I.DT_HORA_ENTradA)))|
----------------------------------------------------|
11|
1|
1|
Oracle文档: https://docs.oracle.com/cd/B14117_01/appdev.101/b10807/06_ora.htm#i36655 https://docs.oracle.com/cd/B14117_01/appdev.101/b10807/13_elems020.htm
解决方法
代码-如您所写-将返回
ORA-06502:PL / SQL:数字或值错误:NULL索引表键值
因为您缺少v_dias.EXTEND
。 ORA-01422
(即TOO_MANY_ROWS
)不会失败;游标不会返回它(除非您有子查询-否则就不会)。
因此,您发布的代码与您所说的代码有误。
由于我没有您的表,因此以下是基于Scott的EMP表的示例:
SQL> CREATE OR REPLACE TYPE tab_dias IS TABLE OF INTEGER;
2 /
Type created.
SQL> CREATE OR REPLACE FUNCTION f_dias (par_deptno IN NUMBER)
2 RETURN tab_dias
3 IS
4 v_dias tab_dias := tab_dias ();
5
6 CURSOR c_dias IS
7 SELECT empno AS dias
8 FROM emp
9 WHERE deptno = par_deptno;
10
11 linha_dias c_dias%ROWTYPE;
12 BEGIN
13 OPEN c_dias;
14
15 LOOP
16 FETCH c_dias INTO linha_dias;
17
18 EXIT WHEN c_dias%NOTFOUND;
19 v_dias.EXTEND; --> this
20 v_dias (v_dias.LAST) := linha_dias.dias;
21 END LOOP;
22
23 CLOSE c_dias;
24
25 RETURN v_dias;
26 END;
27 /
Function created.
测试:
SQL> SELECT f_dias (10) FROM DUAL;
F_DIAS(10)
--------------------------------------------------------------------------------
TAB_DIAS(7782,7839,7934)
或者:
SQL> SELECT * FROM TABLE(f_dias (10));
COLUMN_VALUE
------------
7782
7839
7934
SQL>
代替循环,也许您应该考虑批量收集;它更简单,更有效:
SQL> CREATE OR REPLACE FUNCTION f_dias (par_deptno IN NUMBER)
2 RETURN tab_dias
3 IS
4 v_dias tab_dias := tab_dias ();
5
6 CURSOR c_dias IS
7 SELECT empno AS dias
8 FROM emp
9 WHERE deptno = par_deptno;
10 BEGIN
11 OPEN c_dias;
12
13 FETCH c_dias BULK COLLECT INTO v_dias;
14
15 CLOSE c_dias;
16
17 RETURN v_dias;
18 END;
19 /
Function created.
SQL> SELECT * FROM TABLE (f_dias (10));
COLUMN_VALUE
------------
7782
7839
7934
SQL>
因此,基本上,它有效。还有其他产生TOO_MANY_ROWS
的东西,而不是您发布的代码。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。