2012-04-13 69 views
1

你好我有点困惑,我在这个函数中的游标只返回最上面一行。为什么我的游标只返回最上面一行?

我一直在比较它的几个不同的例子,我见过,我只是没有看到有什么不对。任何指导非常感谢。

FUNCTION FS_A_FUNCTION 
(
    inDate DATE 
) 
RETURN VARCHAR2 IS 

tAnswer  VARCHAR2(1) := 'N'; 
tDates DATE; 

CURSOR c1 IS 

SELECT S.Dates FROM A_TABLE S; 

BEGIN 
OPEN c1; 
LOOP 
    FETCH c1 INTO tDates; 
    EXIT WHEN c1%NOTFOUND; 
END LOOP; 
CLOSE c1; 

IF inDate IN (tDates) THEN 
tAnswer := 'Y'; 

END IF; 

RETURN (tAnswer); 


END FS_A_FUNCTION 

在此先感谢。

回答

4

不太清楚你期望发生什么。在循环tDates将从游标最后看到的任何一行中获得单个值。由于您的select没有order by,这可能是您的表中的任何值。我想你可能是想在循环内检查inDate的值。

我不确定你为什么使用游标,除非真正的逻辑更复杂。如果你正在做什么,我想,你可能只是这样做:

FUNCTION FS_A_FUNCTION 
(
    inDate DATE 
) 
RETURN VARCHAR2 IS 
    tAnswer VARCHAR2(1); 
BEGIN 
    select decode(max(dates), null, 'N', 'Y') 
    into tAnswer 
    from a_table 
    where dates = inDate; 

    RETURN tAnswer; 
END FS_A_FUNCTION; 

...也许BU相同的逻辑更清晰一点:

FUNCTION FS_A_FUNCTION 
(
    inDate DATE 
) 
RETURN VARCHAR2 IS 
    tDates DATE; 
BEGIN 
    select max(dates) 
    into tDates 
    from a_table 
    where dates = inDate; 

    IF tDates IS NULL THEN 
     RETURN 'N'; 
    ELSE 
     RETURN 'Y'; 
    END IF; 
END FS_A_FUNCTION; 

在这两种情况下,我使用max()万一有多行具有相同的日期。

+0

这不是正确的解决方案。如果'inDate'没有找到匹配项而不是返回所需的'tAnswer ='N'',它会抛出NO_DATA_FOUND。 – APC 2012-04-14 06:12:45

+0

@APC - 即使使用'max'?我将不得不在稍后尝试。无论如何,捕捉异常可能会更整洁(或更清晰的意图)。 – 2012-04-14 06:27:58

+0

不,你说得对。我错过了MAX()的意义 – APC 2012-04-14 13:17:28

2

您正在测试,如果存在于你的表的dates领域inDate,但循环结束后,才,所以参考tDates将查询的最后一个记录。

您可以通过简单地检查是否存在记录的日期做到这一点:

cursor c1 is 
    select * 
    from A_TABLE 
    where Dates = inDate; 

正如你可以看到,有没有必要做一个循环。