我编写了一个读取函数,该函数返回具有多行的表。
CREATE OR REPLACE FUNCTION fn_READ(D1 in VARCHAR2,D2 in Varchar2)
return T_DATA_Table is dipass T_DATA_Table;
BEGIN
select T_DATA_OBJ(ID, DATA_START, DATA_END, CHECK_DATA_START,
CHECK_DATA_END )
bulk collect into dipass
from.......
在每一行中,我都有一个ID和4列,类型为DATETIME。
驱动的“ Tha列”是DATA_START和DATA_END。
如果CHECK_DATA_START和CHECK_DATA_END在DATA_START和DATA_END之间,则 我需要生成多个连续的行
否则,我只需要用DATA_START和DATA_END报告1行。
我假设格式数据为“ MM-DD-YYYY”
ROW1:
ID=1
DATA_START=03-04-2016 DATA_END=12-26-2018
CHECK_DATA_START=03-01-2018 CHECK_DATA_END =08-31-2018
ROW2:
ID=2
DATA_START=03-12-2017 DATA_END=12-26-2018
CHECK_DATA_START=03-01-2015 CHECK_DATA_END =08-31-2015
我的结果应该是
ID DATA1 DATA2
1 - 03-04-2016 - 02-28-2018
1 - 03-01-2018 - 08-31-2018
1 - 09-01-2018 - 12-26-2018
2 - 03-12-2017 - 12-26-2018
,结果应写在以下现有对象中
CREATE OR REPLACE TYPE T_Data_Table AS OBJECT
(ID NUMBER(10), DATA1 DATE, DATA2 DATE);
/
我将从“ CURSOR”功能中收到的信息
现在,我以为可以使用游标来解决问题,但是我不知道这是否是更好的方法,而且由于我收到错误,我很难制作出准确的游标 当我尝试插入行时,因为“ dipdata”表或视图不存在。
我不确定这是否是最好的方法。
再次感谢。
这是我的光标功能
CREATE OR REPLACE FUNCTION fn_myfunc_CUR()
return T_Data_Table is
dipdata T_Data_Table ;
CURSOR cur_data IS
SELECT * FROM TABLE(fn_myfunction))
r_data cur_data%ROWTYPE;
BEGIN
OPEN cur_data;
LOOP
FETCH cur_data INTO r_data;
EXIT WHEN cur_data%NOTFOUND;
if (CHECK_DATA_START between DATA_START and DATA_END) and
(CHECK_DATA_END between DATA_START and DATA_END) then
INSERT INTO dipdata (ID, DATA1, DATA2)
VALUES (r_data.ID, DATA_START, CHECK_DATA_START -1);
INSERT INTO dipdata (ID, DATA1, DATA2)
VALUES (r_data.ID, CHECK_DATA_START, CHECK_DATA_END );
INSERT INTO dipdata (ID, DATA1, DATA2)
VALUES (r_data.ID, CHECK_DATA_END +1, DATA_END);
else
INSERT INTO dipdata (ID,DATA1,DATA2)
VALUES (r_data.ID, DATA_START, DATA_END);
end if;
DBMS_OUTPUT.PUT_LINE( 'etcc...');
END LOOP;
CLOSE cur_data;
RETURN dipdata;
END;
更新:
我找到了这个解决方案,但我不知道这是否是更好的方法:
CREATE OR REPLACE FUNCTION PMS.fn_myfunc_CUR
return T_OBJ_TABLE is dipdata T_OBJ_TABLE ;
V_TABLE T_OBJ_TABLE;
vRow T_OBJ;
CURSOR cur_data IS
SELECT * FROM TABLE(fn_READ('01-01-2018','12-31-2018'));
Index NUMBER :=1;
r_data cur_data%ROWTYPE;
BEGIN
OPEN cur_data;
V_TABLE := T_OBJ_TABLE();
V_TABLE.EXTEND;
LOOP
FETCH cur_data INTO r_data;
EXIT WHEN cur_data%NOTFOUND;
if (CHECK_DATA_START between DATA_START and DATA_END) and
(CHECK_DATA_END between DATA_START and DATA_END) then
vRow := T_OBJ(r_data.id, r_data.DATA_START,
r_data.CHECK_DATA_START -1);
V_TABLE(Index) := vRow;
Index :=Index+1
V_TABLE.EXTEND(1);
vRow := T_OBJ(r_data.id, r_data.CHECK_DATA_START,
r_data.CHECK_DATA_END -1);
V_TABLE(Index) := vRow;
Index :=Index+1
V_TABLE.EXTEND(1);
vRow := T_OBJ(r_data.id, r_data.CHECK_DATA_END +1,
r_data.DATA_END);
V_TABLE(Index) := vRow;
Index :=Index+1
V_TABLE.EXTEND(1);
else
vRow := T_OBJ(r_data.id, r_data.DATA_START,
r_data.DATA_END);
V_TABLE(Index) := vRow;
Index := Index +1;
V_TABLE.EXTEND(1);
end if;
END LOOP;
CLOSE cur_data;
RETURN v_table;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error');
RAISE;
END fn_myfunc_CUR;
/