表:

SQL> select b.index_code, b.amount from cin_circ_org_index_amount b;
 
INDEX_CODE               AMOUNT
-------------------- ----------
a64210170               9830.91
a64210171               2626.43
a64210172               7204.48
a64210173              94356.82
a64210190             109364.48
a64210191              94356.82
a64210192               5176.75
a64210193               9830.91
a64210194               2626.43 

 

SQL> select b.index_code, a.operator, a.right_expression
  2    from cin_circ_verify_formulas a, cin_circ_indexes b
  3   where a.left_index_id = b.index_id;
 
INDEX_CODE                                         OPERATOR RIGHT_EXPRESSION
-------------------------------------------------- -------- --------------------------------------------------------------------------------
a10010001                                          =        a10010001+a10020004
a10020001                                          <=       a10020001+a10020004*a10010001
a10020004                                          =        a10020004*a10020005
a10020005                                          =        a10020005+a10020005

 

 解析程序:

---验证公式字符串解析
  procedure sec_calc_indexes_str(p_str         in out varchar2,
                                 p_loc         in out integer,
                                 p_period_name varchar2,
                                 p_rep_org_id  number,
                                 p_data_org_id number,
                                 p_fqc_flag    number,
                                 p_index_type  varchar2) is
  
    j        integer;
    v_length number;
    x        varchar2(3000);
  
    y        varchar2(1);
    v_amount varchar2(500); --指标金额
  
  begin
  
    y := 'X';
    x := p_str;
    select length(x) into v_length from dual;
    while (y = 'X' or y = 'Y') loop
      if substr(x, p_loc, 1) is not null and
         (upper(substr(x, p_loc, 1)) <> lower(substr(x, p_loc, 1)) or
          nvl(translate(substr(x, p_loc, 1), '\1234567890', '\'),
              'is number') = 'is number') then
        if y = 'X' then
          j := p_loc;
        end if;
        y := 'Y';
      else
        if y = 'Y' then
          y := 'Z';
        end if;
        --exit;
      end if;
      p_loc := p_loc + 1;
    end loop;
    p_loc := p_loc - 1;
    --在此需要计算 v_amount 的值
    begin
      select nvl(amount, 0)
        into v_amount
        from cin_circ_org_index_amount a
       where period = p_period_name
         and rep_org_id = p_rep_org_id
         and rep_data_org_id = p_data_org_id
         and index_code = substr(x, j, p_loc - j)
         and fqc_flag = p_fqc_flag
         and a.index_type = p_index_type; --add
      if to_number(v_amount) < 0 then
        v_amount := '(' || v_amount || ')';
      end if;
    exception
      when no_data_found then
        v_amount := 0;
    end;
    --v_amount := 1999999;
    p_str := substr(x, 1, j - 1) || v_amount || substr(x, p_loc);
    p_loc := length(substr(x, 1, j - 1) || v_amount) + 1;
    if length(rtrim(p_str)) > p_loc + 7 then
      sec_calc_indexes_str(p_str,
                           p_loc,
                           p_period_name,
                           p_rep_org_id,
                           p_data_org_id,
                           p_fqc_flag,
                           p_index_type);
    
    end if;
  end sec_calc_indexes_str;
 begin
          v_str     := sec_calc_index_rec.right_expression;
          v_old_str := sec_calc_index_rec.right_expression;
          dbms_output.put_line(v_str);
          v_loc := 1;
          sec_calc_indexes_str(v_str,
                               v_loc,
                               p_period_name,
                               p_rep_org_id,
                               data_org_rec.rep_data_org_id,
                               p_fqc_flag,
                               p_index_type);
          --dbms_output.put_line('select '||v_str||' from dual ');
          execute immediate 'select ' || v_str || ' from dual ' --动态sql,计算右边公式值
            into v_right_amount;
        
          if v_right_amount is null then
            v_right_amount := 0;
          end if;
        
          if sec_calc_index_rec.operator = '=' and
             v_left_amount = v_right_amount then
            v_comparison_opt := TRUE;
          elsif sec_calc_index_rec.operator = '>=' and
                v_left_amount >= v_right_amount then
            v_comparison_opt := TRUE;
          elsif sec_calc_index_rec.operator = '<=' and
                v_left_amount <= v_right_amount then
            v_comparison_opt := TRUE;
          elsif sec_calc_index_rec.operator = '<>' and
                v_left_amount <> v_right_amount then
            v_comparison_opt := TRUE;
          else
            v_comparison_opt := FALSE;
          end if;

 

 

  

 

 

 

posted on 2012-07-04 17:02  小波Ooo  阅读(4019)  评论(0编辑  收藏  举报