从Oracle 11中的Cursor FETCH生成表类型

时间:2019-05-18 11:17:35

标签: oracle plsql

我编写了一个读取函数,该函数返回具有多行的表。

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;
/

0 个答案:

没有答案