2

我创建了一个返回 SYS_REFCURSOR 的 oracle 函数。问题是我需要返回的数据可能是由两个不同的查询产生的。基本上,如果第一个查询没有返回数据,那么我需要运行一个不同的查询,然后返回 refcursor。

这是我的大创意

    FUNCTION F_RETURN_RECORD(
              P_VAL in NUMBER)  
                RETURN SYS_REFCURSOR AS TYPE R_CURSOR IS REF CURSOR;
                my_record_1 R_CURSOR;
                processed_record R_CURSOR;
         BEGIN
          OPEN my_record_1 FOR select e.COL1, e.COL2,a.COL1,e.COL3, e.COL4, 
                                         e.COL5, e.COL6, e.COL7, e.COL8, e.COL9,
                                         e.COL10, e.COL11
                                  from table1 e
                                  inner join table2 a on e.COL2=a.COL2
                                  where e.COL1=P_VAL;

          if my_record_1%notfound
            then
                close my_record_1;
                OPEN processed_record for select e.COL1, e.COL2,a.COL1,e.COL3, e.COL4, 
                                         e.COL5, e.COL6, e.COL7, e.COL8, e.COL9,
                                         e.COL10, e.COL11, e.COL12, e.COL13, e.COL14
                                  from table3 e
                                  inner join table2 a on e.COL2=a.COL2
                                  inner join table 4 b on a.col1=b.col2
                                  where e.COL1=P_VAL;                                   
                return processed_record;
          end if;
          DBMS_OUTPUT.PUT_LINE('Returning data.................');

          return my_record_1;       
 END F_RETURN_RECORD;

无论出于何种原因if my_record_1%notfound,检查都不起作用。我想我的问题是如何检查my_record_1游标是否不包含任何数据?

谢谢

4

2 回答 2

2

我注意到该过程中使用的两个查询的一些共同特征:

光标查询选项 1:

 select e.COL1, e.COL2,a.COL1,e.COL3, e.COL4, 
     e.COL5, e.COL6, e.COL7, e.COL8, e.COL9,
     e.COL10,e.COL11, e.COL12, e.COL13, e.COL14
   from table1 e
  where e.COL1=P_VAL;                                 

 inner join table2 a on e.COL2=a.COL2

table1必须具有相似的结构,table3因为两者在两个不同的查询中使用相同。

光标查询选项 2:

 select e.COL1, e.COL2,a.COL1,e.COL3, e.COL4, 
     e.COL5, e.COL6, e.COL7, e.COL8, e.COL9,
     e.COL10,e.COL11, e.COL12, e.COL13, e.COL14
   from table3 e
  where e.COL1=P_VAL;                                 

 inner join table2 a on e.COL2=a.COL2
 inner join table4 b on a.col1=b.col2

如果选项 1 没有返回结果(未找到数据),则使用此查询(选项 2)。它与查询的主表 ( table3) 不同,并添加了一个额外的 INNER JOIN table4

 FUNCTION F_RETURN_RECORD (P_VAL IN NUMBER) RETURN SYS_REFCURSOR AS TYPE R_CURSOR
    IS REF CURSOR;
    my_record_1        R_CURSOR;
    processed_record   R_CURSOR;

 BEGIN

 OPEN my_record_1 FOR

 WITH        
    OPT1 AS (SELECT e.col1, e.col2, e.col3, e.col4, ..., e.col14
               FROM table1 e
              INNER JOIN table2 a on e.col2 = a.col2
              WHERE e.col1 = P_VAL),

    OPT2 AS (SELECT e.col1, e.col2, e.col3, e.col4, ..., e.col14
               FROM table1 e
              INNER JOIN table2 a on e.col2 = a.col2
              INNER JOIN table4 b on a.col1 = b.col2
              WHERE e.col1 = P_VAL),

    SELECT NVL(opt1.col1, opt2.col1) as col1,
       NVL(opt1.col2, opt2.col2) as col2,
       NVL(opt1.col3, opt2.col3) as col3,
       NVL(opt1.col4, opt2.col4) as col4,
        ....

       NVL(opt1.col3, opt2.col3) as col13,
       NVL(opt1.col4, opt2.col4) as col14

      FROM OPT2
      LEFT OUTER JOIN OPT1 on OPT2.col1 = OPT1.col1;

      return my_record_1;

  END F_RETURN_RECORD;

我还可以看到 UNION 或 UNION ALL 运算符如何也可以提供结果。在我的方法中,我利用JOINS来管理结果。

于 2014-03-26T21:07:54.653 回答
0

我认为您可以通过仅使用 FOR 循环而不是使用 %NOTFOUND 来简化整个代码。这是您可以尝试的示例代码示例。

CREATE OR REPLACE FUNCTION F_RETURN_RECORD(
    P_VAL IN NUMBER)
  RETURN SYS_REFCURSOR
AS
TYPE R_CURSOR
IS
  REF
  CURSOR;
    my_record_1 R_CURSOR;
    processed_record R_CURSOR;
    cur_count NUMBER;
  BEGIN
    cur_count:=0;
    --OPEN my_record_1 FOR select * FROM AVRAJIT;
    FOR rec IN
    (SELECT query
    )
  LOOP
    cur_count:=cur_count+1;
  END LOOP;
  --if my_record_1%notfound
  --then
  -- close my_record_1;
  IF cur_count <> 1 THEN
    OPEN processed_record FOR SELECT query;
    RETURN processed_record;
  END IF;
  DBMS_OUTPUT.PUT_LINE('Returning data.................');
  RETURN my_record_1;
END F_RETURN_RECORD;
于 2014-03-27T07:37:25.820 回答