Oracle DB2 做数据库兼容,DB2 中 to_char 方法实现

-- 小数位数最多到9位,第十位四舍五入不在显示了
CREATE FUNCTION TO_CHAR(v_value double,v_decimal int) -- v_value 传入的值,v_decimal小数位数(暂未实现主要是为了做保留小数位数使用,此参数可以不要)
RETURNS VARCHAR(128)
LANGUAGE SQL
BEGIN ATOMIC
declare v_result_t VARCHAR(128); -- 返回的结果(临时变量)
declare v_result VARCHAR(128); -- 返回的结果
declare e_index int; -- E 的索引位置
declare e_last_str varchar(128); -- E后边的数
declare e_last_int int; -- E后边的数
declare e_pre_str varchar(128); -- E前边的数
declare dot_index int; --小数点的索引位置
declare tmp varchar(128); -- 临时变量
declare e_pre_last char(2); -- e_pre_str 变量的最后一位数字
declare last_0 int; -- 需要向后补0的个数
declare v_length int; -- 字符串的长度
declare v_pre char(3); -- 字符串前两位
declare v_symbol int; -- 符号位
set v_result_t = rtrim(ltrim(CHAR(v_value))); -- 先直接变成字符串
set e_index = POSSTR(v_result_t,'E'); -- 找到E的索引位置
set v_symbol = POSSTR(v_result_t,'-'); --找到符号位, 如果是1说明是负数,0是正数
if(v_symbol = 1) then
  set v_result_t = SUBSTR(v_result_t,(v_symbol+1)); -- 如果有符号重置为无符号数
  set e_index = e_index-1; -- 并且重置E的索引位置
end if;
if(e_index <= 0) then -- 如果索引不到E说明是整数或有问题直接返回
 return v_result_t;
else

if(v_result_t = '0E0') then -- 加入了对0的特殊处理
    return char(0);
  end if;
 set e_last_str = SUBSTR(v_result_t,(e_index+1)); -- 提取E后边的数
  set e_pre_str = SUBSTR(v_result_t,1,(e_index-1)); -- 提取E前边的数
  set dot_index = POSSTR(e_pre_str,'.'); -- 得到小数点的位置
 set e_last_int = cast(e_last_str as int); -- 把E后边的数转换成int
 if(e_last_int < 0) then -- 如果E是负数,则说明原数是小数
  set tmp = '';
    while (e_last_int<0) do
      set tmp = tmp||'0';
      set e_last_int = e_last_int+1;
    end while;
    set e_pre_str = REPLACE(e_pre_str,'.','');
    set v_result = tmp || e_pre_str;
    set v_result = INSERT(v_result,2,0,'.');
    if(v_symbol = 1) then
      set v_result = '-'||v_result;
    end if;
    return v_result;
  elseif(e_last_int = 0) then -- 如果E是0,说明是整数或是整数小数
   set e_pre_last = substr(e_pre_str,length(e_pre_str)); -- 获取E的前一为数字
   if(e_pre_last = '0') then -- 如果E的前一位数字为0,则说明原数是整数
      set v_result = SUBSTR(e_pre_str,1,(dot_index-1));
    else
     set  v_result = e_pre_str;
    end if;
    if(v_symbol = 1) then
      set v_result = '-'||v_result;
    end if;
    return v_result;
  else -- 如果E大于0,说明是采用了科学计数法,根据E扩大倍数移动小数点
   set e_pre_str = REPLACE(e_pre_str,'.',''); -- 去掉小数点
    set last_0 = ((dot_index+e_last_int) - length(e_pre_str)-1); -- 计算出需要在后边补0的个数
    while (last_0>0) do
      set e_pre_str = e_pre_str||'0';
      set last_0 = last_0-1;
    end while;
   set v_result_t = INSERT(e_pre_str,(dot_index+e_last_int),0,'.');
   -- 处理不合理的值(如:35.||000.123)
   set v_length = length(v_result_t);
   set dot_index = POSSTR(v_result_t,'.');
   if(v_length = dot_index) then
    set v_result_t = REPLACE(v_result_t,'.','');
   end if;
    if(v_length >= 2) then
     set v_pre = substr(v_result_t,1,2);
     if(v_pre = '00') then
      set v_result = '0'||substr(v_result_t,POSSTR(v_result_t,'.'));
     else
        set v_result = v_result_t;
      end if;
    end if;
    if(v_symbol = 1) then
      set v_result = '-'||v_result;
    end if;
    return v_result;
  end if;
end if;
END;

之前写过一个版本但是由于考虑不周有点问题

这次做了修改,并添加添加了负数转换。

版本再次修改,修复了BUG,加入了对0的处理,

 

你可能感兴趣的:(Oracle DB2 做数据库兼容,DB2 中 to_char 方法实现)