2012-04-13 4 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; 

... или, может быть немного более ясной бушель той же логике:

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

Это неправильное решение. Он будет бросать NO_DATA_FOUND, если 'inDate' не находит совпадение, а не возвращает желаемый' tAnswer = 'N''. – APC

+0

@APC - даже с 'max'? Я попробую это позже. Однако уловка может быть более аккуратной (или более четкой). –

+0

Нет, ты прав. Я пропустил значение MAX() – APC

2

Вы проверяете, если inDate существует в dates поле вашего стола, но только после того, как цикл заканчивается, поэтому ссылка на tDates будет последняя запись запроса.

Вы можете сделать это, просто проверяя, существует ли запись с датой:

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

Как вы можете видеть, что нет необходимости делать петлю.

Смежные вопросы