我是PL/SQL
的新手,我想编写一个流水线功能来提取付款的通风细节(主表)。这里的代码
CREATE OR REPLACE FUNCTION F_GetImputationsReglement(Pregid Number) RETURN
ImputationsReglementTable PIPELINED IS
BEGIN
DECLARE
ImputationRow Regimputation%ROWTYPE;
type cc is REF CURSOR RETURN ImputationRow%ROWTYPE;
cur0 cc;
CurrentRow ImputationRow%ROWTYPE ;
out_rec ImputationReglementRow := ImputationReglementRow (null,
null,null, null,null);
vquery VARCHAR2(1000);
l_result ImputationReglementRow;
BEGIN
OPEN cur0 FOR
select * from regimputation WHERE regid = pregid;
loop
Fetch cur0 into CurrentRow;
EXIT WHEN cur0%NOTFOUND;
IF CurrentRow.RIMSENS = 'C' OR CurrentRow.RIMSENS IS NULL THEN
IF CurrentRow.facid IS NOT NULL OR (CurrentRow.facid IS NULL AND
CurrentRow.RIMLETTRAGE IS NULL AND CurrentRow.RUBID IS NOT NULL) THEN
out_rec.REGID := CurrentRow.REGID;
out_rec.FACID := CurrentRow.FACID;
out_rec.RIMMT := CurrentRow.RIMMT;
out_rec.FECORDRE := CurrentRow.FECORDRE;
out_rec.RUBID := CurrentRow.RUBID;
PIPE ROW(out_rec);
ELSE
IF CurrentRow.facid IS NULL AND CurrentRow.RIMLETTRAGE is NOT null
and CurrentRow.RUBID IS NOT NULL THEN
vQuery := 'select * from
table(F_GetImputationsReglement(f_getREGID('''|| CurrentRow.RIMLETTRAGE
||''')))';
EXECUTE IMMEDIATE vquery into l_result;
PIPE ROW(l_result);
END IF;
END IF;
END IF;
END LOOP;
CLOSE cur0;
RETURN;
END;
END;
退出的退出条件是:
IF CurrentRow.RIMSENS = 'C' OR CurrentRow.RIMSENS IS NULL THEN
但是当我执行查询
时select * from table(f_getimputationsReglement(696213))
我收到错误:
ORA-00603 ORACLE服务器会话因致命错误而终止
有没有人知道它是什么?
谢谢。
答案 0 :(得分:1)
如果有机会,我会以简化的方式重写您的代码。我假设了一些东西并准备了一个简短的代码。您可以替换为实际的表列。此外,当您调用递归时,可能是代码进入无限循环并且永远不会退出并抛出您获得的错误。我共享一个简单的代码。如果您在下面看到,请参见下文,代码将在infinte recursion中。
在此示例中,var是对象的表。
CREATE OR REPLACE FUNCTION getSoccerLists
RETURN var
IS
--Initialization
LIST VAR :=var();
list1 VAR :=var();
BEGIN
SELECT v_var( NSO ,NAME) BULK COLLECT INTO LIST FROM TEST;
list1:= getSoccerLists;
RETURN list;
END;
您编码重写:
考虑到你有一个对象:
CREATE TYPE v_var IS OBJECT
(
col1 NUMBER,
col1 NUMBER,
col1 number
);
Create type ImputationsReglementTable is table of v_var;
CREATE OR REPLACE FUNCTION F_GetImputationsReglement( Pregid NUMBER)
RETURN ImputationsReglementTable PIPELINED
IS
BEGIN
var ImputationsReglementTable:=ImputationsReglementTable();
l_result ImputationsReglementTable:=ImputationsReglementTable();
BEGIN
--Assuming table regimputation has col1 , col2 and col2
SELECT *
BULK COLLECT INTO var
FROM regimputation
WHERE regid = pregid;
FOR i IN 1..var.count
loop
IF var(i).COL1 = 'C' OR var(i).col1 IS NULL THEN
IF var(i).col2 IS NOT NULL OR (var(i).col2 IS NULL AND var(i).col1 IS NULL AND var(i).col2 IS NOT NULL) THEN
PIPE ROW(v_var(var(i)));
ELSE
IF var(i).col1 IS NULL AND var(i).col1 IS NOT NULL AND var(i).col2 IS NOT NULL THEN
vQuery := 'select * from table(F_GetImputationsReglement(f_getREGID('''|| var(i).col1 ||''')))';
EXECUTE IMMEDIATE vquery BULK COLLECT INTO l_result;
FOR j IN 1..l_result.count
loop
PIPE ROW(v_var(l_result(j)));
end loop;
END IF;
END IF;
END IF;
END LOOP;
RETURN;
END;
END;
答案 1 :(得分:0)
不是您问题的答案,但我建议您在动态查询中使用绑定变量。 您可以重写以下内容以使用绑定变量:
vquery := 'select * from table(F_GetImputationsReglement(f_getREGID(''' || currentrow.rimlettrage ||
''')))';
execute immediate vquery
into l_result;
到
vquery := 'select * from table(F_GetImputationsReglement(f_getREGID(:rimlettrage)))';
execute immediate vquery
into l_result
using currentrow.rimlettrage;
答案 2 :(得分:0)
谢谢XING的答案,但正如我所说,我是PL / SQL的新手,我没有使用BULK,所以我有很多语法错误。 我修改了我的代码如下,它工作正常:
CREATE OR REPLACE FUNCTION F_GetImputationsReglement(Pregid Number) RETURN
ImputationsReglementTable PIPELINED IS
BEGIN
DECLARE
Type tmpOut is record
(
REGID Number(20),
FACID Number(20),
RIMMT NUMBER(12,3),
FECORDRE Number(3),
RUBID Number(3)
);
ImputationRow Regimputation%ROWTYPE;
type cc is REF CURSOR RETURN ImputationRow%ROWTYPE;
type cc2 is REF CURSOR return tmpOut;
cur0 cc;
cur00 cc2;
CurrentRow ImputationRow%ROWTYPE ;
out_rec ImputationReglementRow :=
ImputationReglementRow (null, null,null, null,null);
CurrentRow2 tmpOut;
BEGIN
OPEN cur0 FOR
select * from regimputation WHERE regid = pregid;
loop
Fetch cur0 into CurrentRow;
EXIT WHEN cur0%NOTFOUND;
IF CurrentRow.RIMSENS = 'C' OR CurrentRow.RIMSENS IS NULL THEN --Condition de sortie
IF CurrentRow.facid IS NOT NULL OR (CurrentRow.facid IS NULL AND CurrentRow.RIMLETTRAGE IS NULL AND CurrentRow.RUBID IS NOT NULL) THEN
out_rec.REGID := CurrentRow.REGID;
out_rec.FACID := CurrentRow.FACID;
out_rec.RIMMT := CurrentRow.RIMMT;
out_rec.FECORDRE := CurrentRow.FECORDRE;
out_rec.RUBID := CurrentRow.RUBID;
dbms_output.put_line('Facture ' || CurrentRow.FACID);
PIPE ROW(out_rec);
ELSE
IF CurrentRow.facid IS NULL AND CurrentRow.RIMLETTRAGE is NOT null and CurrentRow.RUBID IS NOT NULL THEN
open cur00 for
select * from table(F_GetImputationsReglement(f_getREGID(CurrentRow.RIMLETTRAGE)));
loop
Fetch cur00 into CurrentRow2;
EXIT WHEN cur00%NOTFOUND;
out_rec.REGID := CurrentRow2.REGID;
out_rec.FACID := CurrentRow2.FACID;
out_rec.RIMMT := CurrentRow2.RIMMT;
out_rec.FECORDRE := CurrentRow2.FECORDRE;
out_rec.RUBID := CurrentRow2.RUBID;
dbms_output.put_line('Facture ' || CurrentRow2.FACID);
PIPE ROW(out_rec);
END LOOP;
CLOSE cur00;
END IF;
END IF;
END IF;
END LOOP;
CLOSE cur0;
RETURN;
END;
END;