parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Ответ

a_kovalnogov 21.08.2007 19:14

интересный подход в парсере -"ЗАЧЕМ ЭТО НУЖНО ИЛИ КОНКРЕТНЕЕ ЗАДАЧУ".
получается все что делает оракле в хранимых процедурах это фигня - все можно сделать в парсере писать select, insert, update, commit. НЕЕЕ ребяты.

причина 1.
если пакет оракле содержащий только статический скл откомпилировался - в нем 100% ошибок нет,
а если текст sql в auto.p - ошибка вылезет во время выполнения и исправлять ее в коде парсера, да еще вперемешку с экранирующими символами и параметрами не очень удобно.
когда представляю селект на 500 строк с 10 таблицами и пересыпанный параметрами в коде парсера - становитсья дурно.

причина 2.
При изменении чего либо(структур таблиц,тригеров,параметров функций, процедур и др.)которые используются в процедуре возвращающей курсор оракл тыкнет вас в строки содержащие ошибки. исправление которых - минутное дело.

причина 3.
разделение труда.
Оракловую логику и обработки пишет другой человек.
Тот кто на парсере - формы,таблицы,java скрипты и прочую красоту.

причина 4.
никакаой редактор для правки парсеровского кода не сравнится с девелопером или тоадом - предназначеннім для оракле.

причина 5.
скорость выполнения запросов сформированных в парсере меньше чем у статического скл в хранимых процедурах.



а пример простой - у меня уже есть оракловая процедура которая возвращает курсор по номеру больничного.
-- Курсор возвращает БЛ по месяцам
procedure cur_hp_for_months_serv
     (p_hp_id         in     hospital_pages.id%type
     ,p_view          in     number default 2  -- ПРОсмотр - 1 расчет
     ,p_hp_for_months in  out t_hp_for_months) is

-- Количество дней больничного за счет предприятия
   v_count_day_ill_on_firm      number := constants.value_cond_constant_for_date('count_day_ill_on_firm',constants.sal_current_period);

   v_month                      number(2);
   v_year                       number(4);
   v_count_day_ill              number(4);   
   v_account_no_firm            accounts.account_no%type;
   v_account_no_fsi             accounts.account_no%type;

   v_payment_item_on_firm       number;
   v_payment_item_on_fsi        number;

   v_hp_id_initial              number;    -- id родительского больничного (самого первого) 
   v_initial_hp_date_first      date;      -- Дата первичного больничного (самого первого)
   
   v_start_month                number;    -- месяц начала выборки ЗП для средней
   v_start_year                 number;    -- год начала выборки ЗП для средней
   v_average_sal_day            number;    -- среднедневная
   v_average_sal_hour           number;    -- среднечасовая
   v_average_sal_day_percent    number;    -- среднедневная с учетом %
   v_average_sal_hour_percent   number;    -- среднедчасоваы с учетом %
   
   p_time_work_less_6_month     number;    -- Если человек отработал на фабрике меньше чем пол года = 1  
   p_minimum_salary             number;    -- минимальная зп на дату наступления страхового случая
   v_cur                        general.t_cur;

   cursor cr_hp is
      select hp.employee_tab_num    as emp_num
            ,hp.date_first
            ,hp.date_last            
            ,hp.type_hospital_page  
            ,hp.parent
            ,hp.method_calc
            ,hp.percent_pay
            ,hp.postone_id
            ,i.illness_type_code
            ,i.source_pay
        from hospital_pages hp
            ,illnesses i
       where hp.illnesse_num = i.num
         and hp.id = p_hp_id;
   rec_hp                       cr_hp%rowtype;
   v_emp_num                    employees.tab_num%type;   
   v_date_hp_first              hospital_pages.date_first%type;
   v_date_hp_last               hospital_pages.date_last%type;
   v_type_hospital_page         hospital_pages.type_hospital_page%type;   
   v_parent                     hospital_pages.parent%type;
   v_method_calc                hospital_pages.method_calc%type;
   v_percent_pay                hospital_pages.percent_pay%type;
   v_illness_type               illnesses.illness_type_code%type;
   v_source_pay                 illnesses.source_pay%type;
   v_postone_id                 hospital_pages.postone_id%type;
   v_key_hp                     varchar2(300);  -- все параметры больничного

   v_division_num               number;   
   cursor cr_division is
      select po.division_num
        from employee_postones ep
            ,postonefound_orders po
       where ep.postone_id = po.order_num
         and ep.employee_tab_num = v_emp_num
         and ep.date_period = trunc(last_day(constants.sal_current_period));

   -----
   -- курсор возвращает БЛ с разбивкой по месяцам и источникам оплаты (из средств предприятия и ФСС)
   procedure cur_hp_firm
        (p_count_day_ill_on_firm in number
        ,p_hp_firm out t_hp_for_months) is
   begin

   open p_hp_firm for
      select it1.month                                                                as month
            ,it1.year                                                                 as year
            ,it1.date_first                                                           as date_first   
            ,it1.date_last                                                            as date_last
            ,it1.count_festive                                                        as count_festive
            ,it1.count_day_ill                                                        as count_day
            ,it1.count_hours_ill                                                      as count_hours_ill
            ,get_sum_hp(it1.key
                       ,it1.count_day_ill
                       ,it1.count_hours_ill
                       ,v_key_hp)                                                     as payment_sum
            ,it1.payment_code                                                         as payment_code
            ,it1.account                                                              as account
            ,it1.account_no                                                           as account_no
            ,it1.type_hospital_page                                                   as type_hospital_page 
            ,it1.parent                                                               as parent
            ,0                                                                        as return_code
            ,it1.key                                                                  as key
            ,v_key_hp                                                                 as key_hp            
      from 
         (select ur.month
               ,ur.year
               ,min(ur.date_absent)                                                date_first
               ,max(ur.date_absent)                                                date_last
               ,nvl(sum(ur.festive),0)                                             count_festive
               ,nvl(sum(ur.ill),0)                                                 count_day_ill
               ,nvl(sum(ur.count_hours),0)                                         count_hours_ill
               ,ur.payment_code
               ,ac.account_no                                                      account
               ,ac.account_no_alt||' '||ac.account_name                            account_no
               ,ur.type_hospital_page
               ,ur.parent
               ,0                                                                  return_code
               ,ur.month||'^'||ur.year||'^'||ur.payment_code||'^'||ac.account_no   key
           from accounts ac
               ,(select distinct
                        to_number(to_char(a.date_absent,'mm'))  month
                       ,to_number(to_char(a.date_absent,'yyyy'))year
                       ,a.date_absent
                       ,decode(a.timeboard_symbol_code,'х',0,1) festive
                       ,decode(a.timeboard_symbol_code,'х',1,0) ill
                       ,a.count_hours
                       ,v_payment_item_on_firm                  payment_code
                       ,v_account_no_firm                       account_no
                       ,hp.type_hospital_page
                       ,hp.parent
                       ,hp.id
                       ,hp.method_calc
                       ,hp.percent_pay
                   from hospital_pages hp
                       ,v_symbol_hospital_pages a
                  where hp.id = a.hp_id
                    and a.date_absent >= hp.date_first
                    and a.date_absent <= decode(sign(p_count_day_ill_on_firm - (hp.date_last - hp.date_first + 1))
                                                    ,-1,hp.date_first + p_count_day_ill_on_firm - 1
                                                    ,hp.date_last)
                    and hp.id = p_hp_id
                        union all -- + fsi
                 select distinct
                        to_number(to_char(a.date_absent,'mm'))  month
                       ,to_number(to_char(a.date_absent,'yyyy'))year
                       ,a.date_absent
                       ,decode(a.timeboard_symbol_code,'х',0,1) festive
                       ,decode(a.timeboard_symbol_code,'х',1,0) ill
                       ,a.count_hours
                       ,v_payment_item_on_fsi                   payment_code
                       ,v_account_no_fsi                        account_no
                       ,hp.type_hospital_page
                       ,hp.parent
                       ,hp.id
                       ,hp.method_calc
                       ,hp.percent_pay
                   from hospital_pages hp
                       ,v_symbol_hospital_pages a
                  where hp.id = a.hp_id
                    and a.date_absent >= hp.date_first + p_count_day_ill_on_firm and a.date_absent <= hp.date_last
                    and hp.id = p_hp_id) ur
          where ac.account_no = ur.account_no
       group by ur.month
               ,ur.year
               ,ur.payment_code
               ,ac.account_no
               ,ac.account_no_alt
               ,ac.account_name
               ,ur.type_hospital_page
               ,ur.parent
               ,ur.method_calc
               ,ur.percent_pay
       ) it1 
       order by date_first;

   end cur_hp_firm;
   -----
   -- курсор возвращает БЛ с разбивкой по месяцам (источник оплаты - только из средств ФСС)
   procedure cur_hp_fsi(p_hp_fsi out t_hp_for_months) is
   begin

      open p_hp_fsi for
      select it1.month                                                                as month
            ,it1.year                                                                 as year
            ,it1.date_first                                                           as date_first   
            ,it1.date_last                                                            as date_last
            ,it1.count_festive                                                        as count_festive
            ,it1.count_day_ill                                                        as count_day
            ,it1.count_hours_ill                                                      as count_hours_ill
            ,get_sum_hp(it1.key
                       ,it1.count_day_ill
                       ,it1.count_hours_ill
                       ,v_key_hp)                                                     as payment_sum
            ,it1.payment_code                                                         as payment_code 
            ,it1.account                                                              as account
            ,it1.account_no                                                           as account_no
            ,it1.type_hospital_page                                                   as type_hospital_page 
            ,it1.parent                                                               as parent
            ,0                                                                        as return_code
            ,it1.key                                                                  as key
            ,v_key_hp                                                                 as key_hp
      from 
           (select ur.month                                      month 
                 ,ur.year                                        year
                 ,min(ur.date_absent)                            date_first
                 ,max(ur.date_absent)                            date_last
                 ,nvl(sum(ur.festive),0)                         count_festive
                 ,nvl(sum(ur.ill),0)                             count_day_ill
                 ,nvl(sum(ur.count_hours),0)                     count_hours_ill
                 ,ur.payment_code                                payment_code
                 ,ac.account_no                                  account
                 ,ac.account_no_alt||' '||ac.account_name        account_no          -- имя счета и название - для отображения
                 ,ur.type_hospital_page                          type_hospital_page
                 ,ur.parent                                      parent
                 ,0                                              return_code
                 ,ur.month||'^'||ur.year||'^'||ur.payment_code||'^'||ac.account_no
                                                                 key
             from accounts ac
                 ,(select distinct
                          to_number(to_char(a.date_absent,'mm'))  month
                         ,to_number(to_char(a.date_absent,'yyyy'))year
                         ,a.date_absent
                         ,decode(a.timeboard_symbol_code,'х',0,1) festive
                         ,decode(a.timeboard_symbol_code,'х',1,0) ill
                         ,a.count_hours
                         ,v_payment_item_on_fsi                   payment_code
                         ,v_account_no_fsi                        account_no
                         ,a.type_hospital_page
                         ,a.parent
                         ,a.method_calc
                         ,a.percent_pay
                     from v_symbol_hospital_pages a
                    where a.hp_id = p_hp_id) ur
            where ac.account_no = ur.account_no
         group by ur.month
                 ,ur.year
                 ,ur.payment_code
                 ,ac.account_no
                 ,ac.account_no_alt
                 ,ac.account_name
                 ,ur.type_hospital_page
                 ,ur.parent
                 ,ur.method_calc
                 ,ur.percent_pay) it1
         order by date_first;

   end cur_hp_fsi;
   -----
begin

   v_month := to_number(to_char(constants.sal_current_period,'mm'));
   v_year  := to_number(to_char(constants.sal_current_period,'yyyy'));
   -- определяем последний месяц и год выборки средней з-ты для расчета БЛ
   start_period_for_calc_hp(p_hp_id
                           ,v_hp_id_initial  -- out САМЫЙ первичный больничный
                           ,v_initial_hp_date_first -- out дата САМОГО первичного больничного(дата наступления страхового случая)                       
                           ,v_start_month    -- out начальный месяц первичного больничного
                           ,v_start_year
                           );   -- out начальный год первичного больничного
   -- определяем среднуюю з-ту БЛ
  sal_hospital_page.payment_illness (p_hp_id
                                    ,v_start_month
                                    ,v_start_year
                                    ,p_view
                                    ,v_average_sal_day           -- out среднедневная 
                                    ,v_average_sal_hour          -- out среднечаосвая 
                                    ,v_average_sal_day_percent   -- out среднедневная за вычетм %
                                    ,v_average_sal_hour_percent  -- out среднечаосвая за вычетм %
                                    ,v_cur);

   ----- Определяем параметры больничного
   open  cr_hp;
   fetch cr_hp into rec_hp;
   close cr_hp;
       v_emp_num            := rec_hp.emp_num;
       v_date_hp_first      := rec_hp.date_first;
       v_date_hp_last       := rec_hp.date_last;
       v_type_hospital_page := rec_hp.type_hospital_page;
       v_parent             := rec_hp.parent;
       v_method_calc        := rec_hp.method_calc;
       v_percent_pay        := rec_hp.percent_pay;
       v_illness_type       := rec_hp.illness_type_code;
       v_source_pay         := rec_hp.source_pay;
       v_postone_id         := rec_hp.postone_id;
   
   -- определяем подразделение по коду ШЕ и Таб номеру на посдеднюю дату текущего периода
   open  cr_division;
   fetch cr_division into v_division_num;
   close cr_division;
   -------------- определяем есть ли ограничение на 6 месяцев стажа
   get_param_start_hp(v_emp_num
                     ,v_initial_hp_date_first      -- in     дата первоначального больничного
                     ,p_time_work_less_6_month     --    out p_time_work_less_6_month := 1 если человек отработал на фабрике меньше чем пол года
                     ,p_minimum_salary);           --    out минимальная ЗП на момент наступления ситрахового случая (самый первый родительский больничный)

   --- Определяем счета и код начисления для фонда соцстраха 
    v_payment_item_on_fsi   := sal_calculation.payment_item_for_document('БЛ',null,null,null,v_illness_type,null,null,null);
    v_account_no_fsi        := sal_calculation.get_cost_item(v_month,v_year,'БЛ',null,null,null,v_illness_type,null,null,null,null,null);
   --- Определяем счета и код начисления для предприятия
    v_payment_item_on_firm  := constants.value_cond_constant_for_date('payment_item_illnesspay_on_firm',constants.sal_current_period);    
    v_account_no_firm       := sal_calculation.get_cost_item(v_month,v_year,v_payment_item_on_firm);
   -- Формируем Ключ со всеми параметрами больничного (чтоб не плодить кучу полей и передаем в курсор)
   v_key_hp :=  v_emp_num             ||'^'||  --1
                v_date_hp_first       ||'^'||  --2  Дата начала болезни
                v_date_hp_last        ||'^'||  --3  Дата конца  болезни
                v_type_hospital_page  ||'^'||  --4  Тип больничного 0-первый, 1-продолжение предыдущего БЛ
                v_parent              ||'^'||  --5  id Родительский больничный
                v_method_calc         ||'^'||  --6  Метод расчета = 0-расчет ведется по дням, 1- по часам
                v_percent_pay         ||'^'||  --7  % оплаты (зависти от количества лет стажа)
                v_illness_type        ||'^'||  --8  тип заболевания (для видов начисления з-ты) (хвороба,догляд,декрет,виробнича травма,травма)
                v_source_pay          ||'^'||  --9  источник оплаты больничного 1- из средств предприятия и ФСС, 0-только из ФСС 
                ---------------
                v_division_num        ||'^'||  --10 подразделение по коду ШЕ и Таб номеру на посдеднюю дату текущего периода 
                v_payment_item_on_fsi ||'^'||  --11 код начисления для фонда соцстраха
                v_account_no_fsi      ||'^'||  --12 счет для фонда соцстраза 
                v_payment_item_on_firm||'^'||  --13 код начисления для предприятия
                v_account_no_firm     ||'^'||  --14 счет для предприятия
                ---------------   
                v_average_sal_day     ||'^'||  --15 среднедневная 
                v_average_sal_hour    ||'^'||  --16 среднечасовая
                ---------------                   
                p_time_work_less_6_month ||'^'|| --17 1 если человек отработал на фабрике меньше чем пол года
                p_minimum_salary         ||'^'|| --18 минимальная ЗП на дату наступления страхового случая     
                v_postone_id             ||'^'|| --19 Код штатной единицы из больничного (нельзя использовать функции из за уволенных рабочих с больничными)  
                ---------------
                v_average_sal_day_percent ||'^'||--20 среднедневная за вычетм %
                v_average_sal_hour_percent||'^'||--21 среднечаосвая за вычетм %
                v_initial_hp_date_first ; -- 22 дата наступления страхового случая
                
                

   -- Форомируем курсор
   if v_source_pay = 1 then --источник оплаты больничного 1-из средств предприятия и ФСС
      if v_type_hospital_page = 1 then -- 1-продолжение предыдущего БЛ
         -- оперделяем кол-во дней болезни (по предыдущим БЛ)
         v_count_day_ill := count_day_previous_hp(v_parent);
         -- если кол-во дней предыдущих БЛ более или равно 5 значит уже оплачено из средств предприятия
         -- т.е. оплата только из средств ФСС
         if v_count_day_ill >= v_count_day_ill_on_firm then
            cur_hp_fsi(p_hp_for_months);
         else
            -- определяем кол-во дней которые нужно оплатить из средств предприятия
            v_count_day_ill_on_firm := v_count_day_ill_on_firm - v_count_day_ill;
            cur_hp_firm(v_count_day_ill_on_firm,p_hp_for_months);
         end if;
      else  -- первичный БЛ
            cur_hp_firm(v_count_day_ill_on_firm,p_hp_for_months);
      end if;
   else  --0-только из ФСС
      cur_hp_fsi(p_hp_for_months);
   end if;

end cur_hp_for_months_serv;