Как использовать выбор в цикле продолжить, когда оператор? - PullRequest
0 голосов
/ 24 января 2019

Я хочу продолжить oracle-цикл sql, когда нахожу более одного результата в запросе, поэтому мой упрощенный код:

declare
   cursor foo_cursor select * from foo_table;
   foo foo_cursor%ROWTYPE;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      continue when ( -- the next query has entries or an entry, 
                      -- but how do I do this?
         select count(*) from bar_table where bar_column=foo.foo_column
             group by bar_column having count(1)>1;
      )
      insert into uninterresting_table (some_column) VALUES
          (foo.foo_column);
    end loop;
    close foo_cursor;
end;

Ответы [ 3 ]

0 голосов
/ 24 января 2019

если [выберите имеет ... одну и более записей], я хочу перейти к следующей итерации, иначе сделайте больше вещей в этой итерации.

Если в bar_table нет записей, вы хотите выполнить дополнительную обработку, иначе вы можете пропустить обработку.Есть способ сделать это: goto.

О да:)

declare
   cursor foo_cursor select * from foo_table;
   foo foo_cursor%ROWTYPE;
   n pls_integer;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      select count(*) into n
      from bar_table 
      where bar_column=foo.foo_column
      group by bar_column having count(1)>1;

      if n > 0 then
         goto skip_point;
      end if;

      insert into uninterresting_table (some_column) VALUES
          (foo.foo_column);

      << skip_point >>
    end loop;
    close foo_cursor;
end;

Очевидно, вы можете просто поместить весь пропускаемый раздел в ветвь оператора IF .. ELSE,но где в этом веселье?

0 голосов
/ 25 января 2019

Итак, благодаря @APC и @Sentinel - я все еще заставил свою версию работать, но ваши ответы дали мне правильные указания:

declare
   cursor foo_cursor select * from foo_table;
   foo foo_cursor%ROWTYPE;
   n pls_integer
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      begin
         select count(1) into n from bar_table where bar_column=foo.foo_column
             group by bar_column;
         exception when NO_DATA_FOUND then continue;
      end
      continue when (n>1);
      insert into uninterresting_table (some_column) VALUES
          (foo.foo_column);
      -- do some more stuff
    end loop;
    close foo_cursor;
end;
```
0 голосов
/ 24 января 2019

Похоже, что вы хотите воздействовать на записи только в FOO_TABLE, если в BAR_TABLE существует как минимум две связанные записи.Вы можете изменить определение foo_cursor, чтобы учесть это требование, как показано ниже.Таким образом, вам не нужно итеративно проверять наличие записи в BAR_TABLE каждый раз.

declare
   cursor foo_cursor is 
   select * 
     from foo_table foo
    where exists (select 1 from bar_table bar
                   where bar.bar_column = foo.foo_column
                  having count(*) > 1);
   foo foo_cursor%ROWTYPE;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      insert into uninteresting_table (some_column) VALUES
          (foo.foo_column);
    end loop;
    close foo_cursor;
end;
/

С другой стороны, если вы хотите пропустить записи в FOO_TABLE, которые уже имеютдве или более записей в BAR_TABLE, вы можете просто инвертировать проверку существования, и все остальное будет таким же:

declare
   cursor foo_cursor is 
   select * 
     from foo_table foo
    where NOT exists (select 1 from bar_table bar
                       where bar.bar_column = foo.foo_column
                      having count(*) > 1);
   foo foo_cursor%ROWTYPE;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      insert into uninteresting_table (some_column) VALUES
          (foo.foo_column);
    end loop;
    close foo_cursor;
end;
/

Если вы хотите обработать все записи в FOO_TABLE, но выполнять дополнительные действия, когда дваили в BAR_TABLE существует больше записей, вы можете сделать это, изменив свой foo_cursor:

declare
   cursor foo_cursor is 
   select foo.* 
        , case when exists (select 1 from bar_table bar
                             where bar.bar_column = foo.foo_column
                            having count(*) > 1)
               then 'Y'
               else 'N'
          end has_two_or_more
     from foo_table foo;
   foo foo_cursor%ROWTYPE;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      continue when foo.has_two_or_more = 'Y';
      insert into uninteresting_table (some_column) VALUES
          (foo.foo_column);
    end loop;
    close foo_cursor;
end;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...