относительно Oracle PL SQL Loop - PullRequest
       47

относительно Oracle PL SQL Loop

0 голосов
/ 24 октября 2018

Сегодня занимаюсь кодированием.Обнаружена следующая проблема с последовательностями.Этот код в PL / SQL:

Click to see code

не работает должным образом, т.е. последовательность не увеличивается на 10, как я хотел - только на 1. Этот код:

Click to see code

отлично работает.Последовательность увеличивается на 10, как и ожидалось.

Почему это объясняется?

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Вы можете увидеть, что происходит, добавив несколько отладок:

create sequence s42;

set serveroutput on

declare
  cursor c is
    select s42.nextval from dual;
  n pls_integer;
begin
  open c;
  for i in 1..5 loop
    fetch c into n;
    dbms_output.put_line('i: ' || i
      || '; n: ' || n
      || '; found: ' || case when c%found then 'true' else 'false' end);
  end loop;
  close c;
end;
/

i: 1; n: 1; found: true
i: 2; n: 1; found: false
i: 3; n: 1; found: false
i: 4; n: 1; found: false
i: 5; n: 1; found: false


PL/SQL procedure successfully completed.

Вы открываете курсор только один раз, и курсор возвращает только одну строку.Итак, первая выборка находит значение (c%found верно).Вторая и последующие выборки не находят строки, поскольку однострочный набор результатов уже исчерпан.

Короче говоря, nextval выполняется только один раз, поэтому последовательность увеличивается только один раз.

Во второй версии весь запрос повторно выполняется внутри цикла, поэтому nextval вызывается несколько раз, и, следовательно, последовательность также увеличивается несколько раз.

Вы увидите то же самоеесли вы снова открыли курсор внутри цикла:

declare
  cursor c is
    select s42.nextval from dual;
  n pls_integer;
begin
  for i in 1..5 loop
    open c;
    fetch c into n;
    dbms_output.put_line('i: ' || i
      || '; n: ' || n
      || '; found: ' || case when c%found then 'true' else 'false' end);
    close c;
  end loop;  
end;
/

i: 1; n: 2; found: true
i: 2; n: 3; found: true
i: 3; n: 4; found: true
i: 4; n: 5; found: true
i: 5; n: 6; found: true

, но на самом деле это более длинный и более сложный способ сделать select ... into, поскольку он может возвращать только одну строку за раз.

0 голосов
/ 24 октября 2018

Только во втором коде выполняется nextval 10 раз, потому что NEXTVAL вызывается внутри цикла

NEXTVAL вызывает приращение

NEXTVAL: увеличивает последовательность и возвращает следующее значение

Первый код вызывает nextval один раз и сохраняет значение в курсоре, затем то же значение обновляется 10 раз в цикле

...