-- 小數位元最多到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的處理,