create or replace function yf_mzcfmx_byj_xszfs(iStr number) return varchar2 as --小数转分数 v_Str varchar(50); result varchar(50); v_zs varchar2(20); --整数 v_xs varchar2(20); --小数 v_pos int; --小数点位置 v_fm integer; --分母 v_fz integer; --分子 v_zdgys integer; --最大公约数 --求最大公约数 function getZDGYS(iNum1 integer, iNum2 integer) return integer as v_ys integer; --余数 v_num1 integer; v_num2 integer; begin v_num1 := iNum1; v_num2 := iNum2; v_ys := mod(v_num1, v_num2); --辗转相除法 while v_ys <> 0 loop v_num1 := v_num2; v_num2 := v_ys; v_ys := mod(v_num1, v_num2); end loop; return v_num2; end; begin v_Str := trim(iStr); v_pos := instr(v_Str, '.'); --计算小数点位置 if v_pos = 0 then result := v_Str; --纯整数 else if substr(v_Str, 1, 1) = '-' then v_zs := substr(v_Str, 2, v_pos - 2); --整数 else v_zs := substr(v_Str, 1, v_pos - 1); --整数 end if; v_xs := substr(v_Str, v_pos + 1); --小数 if to_number(nvl(v_zs, '0')) = 0 then if substr(v_zs, 1, 1) = '-' then v_zs := '-'; --如果整数为-0则显示负号 else v_zs := ''; --如果整数为0则不显示整数 end if; else v_zs := v_zs || '+'; --整数部份显示样式 end if; v_fz := to_number(v_xs); --分子 v_fm := power(10, length(v_xs)); --分母 v_zdgys := getZDGYS(v_fm, v_fz); --求最大公约数 result := (v_fz / v_zdgys) || '/' || (v_fm / v_zdgys); if substr(v_Str, 1, 1) = '-' then result := '-(' || v_zs || result || ')'; else result := v_zs || result; end if; end if; --针对常见的一些小数进行转换成分数给摆药机打印处方用法用量 if v_pos != 0 then --当小数点后2位是33时,进行特殊转换成1/3 if substr(iStr,instr(iStr,'.')+1,length(iStr))=33 then result := v_zs ||'1/3'; --当小数点后2位是66时,进行特殊转换成2/3 elsif substr(iStr,instr(iStr,'.')+1,length(iStr))=66 then result := v_zs ||'2/3'; --当小数点后2位是17时,进行特殊转换成1/6 elsif substr(iStr,instr(iStr,'.')+1,length(iStr))=17 then result := v_zs ||'1/6'; --当小数点后2位是83时,进行特殊转换成5/6 elsif substr(iStr,instr(iStr,'.')+1,length(iStr))=83 then result := v_zs ||'5/6'; --当小数点后2位是14时,进行特殊转换成1/7 elsif substr(iStr,instr(iStr,'.')+1,length(iStr))=14 then result := v_zs ||'1/7'; --当小数点后2位是13时,进行特殊转换成1/8 elsif substr(iStr,instr(iStr,'.')+1,length(iStr))=13 then result := v_zs ||'1/8'; --当小数点后2位是11时,进行特殊转换成1/9 elsif substr(iStr,instr(iStr,'.')+1,length(iStr))=11 then result := v_zs ||'1/9'; end if; end if; return result; end;