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的处理,