本帖最后由 jjkmm 于 2012-10-08 11:21:01 编辑

解决方案 »

  1.   

    出处 :http://blog.csdn.net/yzsind/article/details/260479801.create or replace function dftof(iStr number) return varchar2 as  
    02.  
    03.  --小数转分数   
    04.  
    05.  -- (decimal fraction) to fraction   
    06.  
    07.  --设计人:叶正盛   
    08.  
    09.  v_Str   varchar(50);  
    10.  
    11.  result  varchar(50);  
    12.  
    13.  v_fh    varchar(1); --负数符号   
    14.  
    15.  v_zs    varchar2(20); --整数   
    16.  
    17.  v_xs    varchar2(20); --小数   
    18.  
    19.  v_pos   int; --小数点位置   
    20.  
    21.  v_fm    integer; --分母   
    22.  
    23.  v_fz    integer; --分子   
    24.  
    25.  v_zdgys integer; --最大公约数   
    26.  
    27.  --求最大公约数   
    28.  
    29.  function getZDGYS(iNum1 integer, iNum2 integer) return integer as  
    30.  
    31.    v_ys   integer; --余数   
    32.  
    33.    v_num1 integer;  
    34.  
    35.    v_num2 integer;  
    36.  
    37.  begin  
    38.  
    39.    v_num1 := iNum1;  
    40.  
    41.    v_num2 := iNum2;  
    42.  
    43.    v_ys   := mod(v_num1, v_num2);  
    44.  
    45.    --辗转相除法   
    46.  
    47.    while v_ys <> 0 loop  
    48.  
    49.      v_num1 := v_num2;  
    50.  
    51.      v_num2 := v_ys;  
    52.  
    53.      v_ys   := mod(v_num1, v_num2);  
    54.  
    55.    end loop;  
    56.  
    57.    return v_num2;  
    58.  
    59.  end;  
    60.  
    61.begin  
    62.  
    63.  v_Str := trim(iStr);  
    64.  
    65.  v_pos := instr(v_Str, '.'); --计算小数点位置   
    66.  
    67.  if v_pos = 0 then  
    68.  
    69.    result := v_Str; --纯整数   
    70.  
    71.  else  
    72.  
    73.    if substr(v_Str, 1, 1) = '-' then  
    74.  
    75.      v_zs := substr(v_Str, 2, v_pos - 2); --整数   
    76.  
    77.    else  
    78.  
    79.      v_zs := substr(v_Str, 1, v_pos - 1); --整数   
    80.  
    81.    end if;  
    82.  
    83.    v_xs := substr(v_Str, v_pos + 1); --小数   
    84.  
    85.    if to_number(nvl(v_zs, '0')) = 0 then  
    86.  
    87.      if substr(v_zs, 1, 1) = '-' then  
    88.  
    89.        v_zs := '-'; --如果整数为-0则显示负号   
    90.  
    91.      else  
    92.  
    93.        v_zs := ''; --如果整数为0则不显示整数   
    94.  
    95.      end if;  
    96.  
    97.    else  
    98.  
    99.      v_zs := v_zs || '+'; --整数部份显示样式   
    100.  
    101.    end if;  
    102.  
    103.    v_fz    := to_number(v_xs); --分子   
    104.  
    105.    v_fm    := power(10, length(v_xs)); --分母   
    106.  
    107.    v_zdgys := getZDGYS(v_fm, v_fz); --求最大公约数   
    108.  
    109.    result  := (v_fz / v_zdgys) || '/' || (v_fm / v_zdgys);  
    110.  
    111.    if substr(v_Str, 1, 1) = '-' then  
    112.  
    113.      result := '-(' || v_zs || result || ')';  
    114.  
    115.    else  
    116.  
    117.      result := v_zs || result;  
    118.  
    119.    end if;  
    120.  
    121.  end if;  
    122.  
    123.  return result;  
    124.  
    125.end;  
      

  2.   

    这个可以自己写个函数,可参考下面函数create or replace function f_gy
    (
      v_num1 in number,
      v_num2 in number

    --author:xwj
    --create date:2012-10-8
    --purpose:除法转换最简的分数形式。例如225/35=45/7
    --algorith:采用辗转相除法求出最大公约数,注意求A和B的最大公约数=求B和A的最大公约数
    --
    return varchar2 is
      v_result varchar2(3000);
      v_divide_result number := 0; --除法结果取整
      v_divide_remain number := 0; --除法余数
      v_len_xs1 number := 0; --第一个参数小数长度
      v_len_xs2 number := 0; --第二个参数小数长度
      v_max_len number := 0; --两个小数长度最大值
      v_sjz varchar2(30) := '1'; --十进制进位数
      v_num1_zs number;  --第一个参数转换成整数
      v_num2_zs number;  --第二个参数转换成整数
    begin
      --首先判断输入的两个参数是否是小数
      if instr(v_num1,'.') > 0 then
        v_len_xs1 := length(substr(v_num1,instr(v_num1,'.')+1));
      end if;
      
      if instr(v_num2,'.') > 0 then
        v_len_xs2 := length(substr(v_num1,instr(v_num1,'.')+1));
      end if;
      
      --两个小数里面取最大值
      if v_len_xs1 >= v_len_xs2 then
        v_max_len := v_len_xs1;
      else
        v_max_len := v_len_xs2;
      end if;
      
      --生成取整需要的进位数
      for i in 1..v_max_len loop
        v_sjz := v_sjz || '0';
      end loop;
      
      v_num1_zs := v_num1*to_number(v_sjz);
      v_num2_zs := v_num2*to_number(v_sjz);
      --保存第一次除法结果备用 
      v_max_len := trunc(v_num1_zs/v_num2_zs);   
      
      --由于A和B的最大公约数=求B和A的最大公约数,因此取NUM1为两个参数中的大数
      if v_num1_zs < v_num2_zs then
        v_divide_result := v_num1_zs;
        v_num1_zs := v_num2_zs;
        v_num2_zs := v_divide_result;
      end if;
      
      --dbms_output.put_line(v_num1_zs||''||v_num2_zs);
      
      loop
        --除法结果取整
        v_divide_result := trunc(v_num1_zs/v_num2_zs);
        
        --除法取余数    
        v_divide_remain := v_num1_zs - v_num2_zs * v_divide_result;
        --循环到一直余数为0,那个时候的v_num2_zs为最大公约数
        if v_divide_remain = 0 then
          exit;
        end if;
        --
        v_num1_zs := v_num2_zs;
        v_num2_zs := v_divide_remain;
        
      end loop;
        
      
      --找到最大公约数之后,就可以返回最简单分数结果
      if v_max_len > 0 then
        --如果最大公约数=1,则分子需减去v_max_len*v_num2
        if v_num2_zs = 1 then
          v_result := to_char(v_max_len) || '+' || to_char(v_num1*to_number(v_sjz)/v_num2_zs - v_max_len*v_num2*to_number(v_sjz)) 
                    || '/' || to_char(v_num2*to_number(v_sjz)/v_num2_zs);
        else
          v_result := to_char(v_max_len) || '+' || to_char(v_num1*to_number(v_sjz)/v_num2_zs) 
                    || '/' || to_char(v_num2*to_number(v_sjz)/v_num2_zs);
        end if;
      else
        v_result := to_char(v_num1*to_number(v_sjz)/v_num2_zs) 
                    || '/' || to_char(v_num2*to_number(v_sjz)/v_num2_zs);
      end if;
          
      return(v_result);
      
    end f_gy;