Можно ли переписать эту процедуру, используя таблицы VARS? - PullRequest
0 голосов
/ 27 октября 2010

У меня есть простая процедура удаления, которая использует курсор.Я где-то читал, что табличные переменные предпочтительнее курсоров.

CREATE OR REPLACE PROCEDURE SMTAPP.LF_PLAN_VYMAZ (Str_oz varchar2, Num_rok number, Num_mesiac number, Str_s_trc_id varchar2) IS
    var_LF_PLAN_ID Number(20);
    cursor cur_plan is select id from lp_plan where lf_plan_id=var_LF_PLAN_ID;
BEGIN
   select ID into var_LF_PLAN_ID from lf_plan where oz=Str_oz and rok=Num_rok and mesiac=Num_mesiac and s_trc_id=Str_s_trc_id;
   for c1 in cur_plan loop
        delete from LP_PLAN_DEN where lp_plan_id=c1.id;
   end loop;
   delete from LP_PLAN where lf_plan_id=var_LF_PLAN_ID;
   delete from LP_PLAN_HIST where LF_PLAN_ID=var_LF_PLAN_ID;
   delete from LF_PLAN where id=var_LF_PLAN_ID;
END;

Ответы [ 2 ]

2 голосов
/ 27 октября 2010

Я не знаю, что такое «табличная переменная» (у меня такое ощущение, что это термин SQL Server?), Но я бы не использовал курсор здесь, я бы сделал это:

CREATE OR REPLACE PROCEDURE SMTAPP.LF_PLAN_VYMAZ 
   (Str_oz varchar2, Num_rok number, Num_mesiac number, Str_s_trc_id varchar2)
IS
    var_LF_PLAN_ID Number(20);
BEGIN
   select ID into var_LF_PLAN_ID
   from lf_plan
   where oz=Str_oz and rok=Num_rok and mesiac=Num_mesiac
   and s_trc_id=Str_s_trc_id;

   delete from LP_PLAN_DEN where lp_plan_id in 
      (select id from lp_plan where lf_plan_id=var_LF_PLAN_ID);
   delete from LP_PLAN where lf_plan_id=var_LF_PLAN_ID;
   delete from LP_PLAN_HIST where LF_PLAN_ID=var_LF_PLAN_ID;
   delete from LF_PLAN where id=var_LF_PLAN_ID;
END;

РЕДАКТИРОВАТЬ : «Таблица var» действительно концепция SQL Server

Я бы закодировал это, как показано выше, однако, поскольку вы специально хотите посмотреть, как сделать это с коллекцией, вот другой способ, который использует один:

CREATE OR REPLACE PROCEDURE SMTAPP.LF_PLAN_VYMAZ 
   (Str_oz varchar2, Num_rok number, Num_mesiac number, Str_s_trc_id varchar2)
IS
    var_LF_PLAN_ID Number(20);
    TYPE id_table IS TABLE OF lp_plan.id%TYPE;
    var_ids id_table_type;
BEGIN
   select ID into var_LF_PLAN_ID
   from lf_plan
   where oz=Str_oz and rok=Num_rok and mesiac=Num_mesiac
   and s_trc_id=Str_s_trc_id;

   select id from lp_plan 
   bulk collect into var_ids
   where lf_plan_id=var_LF_PLAN_ID;

   forall i in var_ids.FIRST..var_ids.LAST
     delete from LP_PLAN_DEN where lp_plan_id = var_ids(i);

   delete from LP_PLAN where lf_plan_id=var_LF_PLAN_ID;
   delete from LP_PLAN_HIST where LF_PLAN_ID=var_LF_PLAN_ID;
   delete from LF_PLAN where id=var_LF_PLAN_ID;
END;

Это, вероятно, не будет работать так же хорошо, как предыдущий метод.

0 голосов
/ 27 октября 2010

Возможно, это не имеет прямого отношения к вопросу, но ...

Я бы сделал это, как подсказывает Тони в большинстве случаев;но если бы я оказался в ситуации, когда нужна версия курсора, чтобы можно было выполнить какую-то другую обработку на основе каждой удаленной строки, я бы использовал функциональность FOR UPDATE и WHERE CURRENT OF:

CREATE OR REPLACE PROCEDURE SMTAPP.LF_PLAN_VYMAZ (Str_oz varchar2, Num_rok number,
    Num_mesiac number, Str_s_trc_id varchar2)
IS
    var_LF_PLAN_ID Number(20);
    cursor cur_plan is
        select id from lp_plan where lf_plan_id=var_LF_PLAN_ID for update;
BEGIN
    select ID into var_LF_PLAN_ID
    from lf_plan
    where oz=Str_oz and rok=Num_rok and mesiac=Num_mesiac and s_trc_id=Str_s_trc_id;

    for c1 in cur_plan loop
        delete from LP_PLAN_DEN where current of cur_plan;
    end loop;

    delete from LP_PLAN where lf_plan_id=var_LF_PLAN_ID;
    delete from LP_PLAN_HIST where LF_PLAN_ID=var_LF_PLAN_ID;
    delete from LF_PLAN where id=var_LF_PLAN_ID;
END;

Это заблокирует интересующие вас строки и может сделать цель удаления более понятной.

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