FETCH INTO не вызывает исключение, если набор пуст, не так ли? - PullRequest
2 голосов
/ 03 февраля 2011

Вот пример кода, который я пытаюсь отладить:

BEGIN
            OPEN bservice (coservice.prod_id);

            FETCH bservice
            INTO  v_billing_alias_id, v_billing_service_uom_id, v_summary_remarks;

            CLOSE bservice;

            v_service_found := 1;
        -- An empty fetch is expected for some services.
        EXCEPTION
            WHEN OTHERS THEN
                v_service_found := 0;
        END;

Когда параметризованный курсор bservice (prod_id) пуст, он выбирает NULL в три переменные и не выдает исключение.

Итак, кто бы ни написал этот код, ожидая, что он выдаст исключение, он ошибался, верно? Кажется, что комментарий подразумевает, что ожидается пустая выборка, а затем он устанавливает флаг для последующей обработки, но я думаю, что этот код также не может быть протестирован с пустыми наборами.

Очевидно, что он должен использовать bservice% NOTFOUND или bservice% FOUND или аналогичный.

Ответы [ 2 ]

4 голосов
/ 03 февраля 2011

Когда параметризованный курсор bservice (prod_id) пуст, он выбирает NULL в три переменные и не выдает исключение.

Неправильно

Когда т пусто , оно ничего не выбирает и не перезаписывает никакие значения.

declare

  cursor c(dt in date) is 
    select dummy from dual 
     where dt > sysdate;

  dummy_ dual.dummy%type;

begin

  open c(sysdate + 2);
  fetch c into dummy_;
  close c;
  dbms_output.put_line('1: ' || dummy_);

  open c(sysdate - 2);
  fetch c into dummy_;
  close c;
  dbms_output.put_line('2: ' || dummy_);

end;
/

печатает

1: X
2: X

Таким образом, любой, кто написал этот код, ожидал, что он выдаст исключениенеправильно, верно? Да

Очевидно, что он должен использовать bservice% NOTFOUND или bservice% FOUND или аналогичный. Да

4 голосов
/ 03 февраля 2011

Если вы хотите узнать, вернул ли курсор какой-либо результат, используйте атрибут курсора% FOUND:

        OPEN bservice (coservice.prod_id);

        FETCH bservice
        INTO  v_billing_alias_id, v_billing_service_uom_id, v_summary_remarks;

        -- An empty fetch is expected for some services.
        IF (bservice%FOUND) THEN
          v_service_found := 1;
        ELSE
          v_service_found := 0;
        END IF

        CLOSE bservice;

из атрибуты курсора

% FOUND
  • Возвращает INVALID_CURSOR, если курсор объявлен, но не открыт;или если курсор был закрыт.
  • Возвращает NULL, если курсор открыт, но выборка не была выполнена
  • Возвращает TRUE, если была выполнена успешная выборка
  • Возвращает FALSE, еслистрока не была возвращена.
...