Инструкция выбора курсора, где условие изменяется в зависимости от условия - PullRequest
0 голосов
/ 21 сентября 2018

Я использую Курсор в процедуре, здесь я не использую Массовый сбор, так как у меня много вычислений для записей, извлеченных из Курсора.

В операторе Select Курсора Где предложение изменяется в зависимости от условия, яя пытаюсь использовать код, как показано ниже, но он дает мне ошибку:

Ошибка (19,12): PLS-00103: Обнаружен символ "c_recs" при ожидании одного из следующих действий:: =.(@%;

 create or replace PROCEDURE        "test" 
  (fromdate_in               IN varchar2,
     todate_in               IN varchar2,
     atype_in                IN number
    )
 is

 begin
  if atype_in = 01 then  
    cursor c_recs IS SELECT cname FROM A_AUD AA WHERE AA.atime BETWEEN to_date( '' || fromdate_in || '' ,'DD/MM/RRRR')
    AND to_date('' || todate_in || '','DD/MM/RRRR') AND AA.CTYPE IN ('RAlert');
 elsif  atype_in = 02
   cursor c_auditrecs IS  SELECT cname FROM A_AUD AA WHERE AA.atime BETWEEN to_date( '' || fromdate_in || '' ,'DD/MM/RRRR')
    AND to_date('' || todate_in || '','DD/MM/RRRR') AND AA.CTYPE IN ('DAlert');
 end if;
end


begin
--more logic

 FOR rec IN c_recs LOOP
  ---calculations

 END LOOP;

END test;

Я не хочу использовать SYS_REFCURSOR из сети, я читал, что курсоры немного лучше, чем ref-курсоры.

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Лучшим и эффективным вариантом было бы сделать это одним оператором без курсоров.Но это зависит от того, что вы хотите сделать. Если вам нужно выполнить dmls на основе записей курсора, желательно сделать это в одном выражении.

Если вы действительно хотите что-то обрабатывать в цикле, используйтенеявный цикл курсора, который эквивалентен (а иногда и более эффективен) явным курсорам.

Запрос выбора также можно упростить с помощью условной логики, а не IF / ELSE.

CREATE OR REPLACE PROCEDURE "test" (
     fromdate_in   IN VARCHAR2,
     todate_in     IN VARCHAR2,
     atype_in
          in NUMBER
) is begin 

for cur in (
     SELECT cname
     FROM a_aud aa
     WHERE aa.time BETWEEN TO_DATE(fromdate_in,'dd/mm/rrrr') 
     AND TO_DATE(todate_in,'dd/mm/rrrr') AND (
          (
               atype_in = '01' AND aa.ctype = 'RAlert'
          ) OR (
               atype_in = '02' AND aa.ctype = 'DAlert'
          )
     )
) loop
                         ---calculations
    do_something_with(cur.cname)
   end loop;
 end;  
 /

Я бытакже предложите вам указывать тип аргументов в качестве дат и передавать переменные непосредственно из вызывающего блока, а не преобразовывать их внутри sql / cursor. Это позволит избежать TO_DATE преобразования.

0 голосов
/ 21 сентября 2018

CASE в объявлении курсора решает эту проблему:

DECLARE
   CURSOR c_recs
   IS
      SELECT cname
        FROM a_aud aa
       WHERE     aa.time BETWEEN TO_DATE (fromdate_in, 'dd/mm/rrrr')
                             AND TO_DATE (todate_in, 'dd/mm/rrrr')
             AND aa.ctype =
                    CASE
                       WHEN atype_in = '01' THEN 'RAlert'
                       WHEN atype_in = '02' THEN 'DAlert'
                    END;
BEGIN
   FOR rec IN c_recs
   LOOP
      NULL;
   END LOOP;
END;

Я не могу прокомментировать ваше утверждение refcursor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...