[SQL]資料庫使用FLOAT欄位來記錄金額對嗎?

  • 31732
  • 0
  • SQL
  • 2012-10-05

[SQL]資料庫使用FLOAT欄位來記錄金額對嗎?

今天一早到公司,同事就反應資料庫加密時,原本金額是1000039,解密出來卻是1000040。

和同事看了一下,感覺好像是因為資料型態造成的呢?

於是發現資料庫的欄位居然是FLOAT。

問題解開了,因為資料型態是FLOAT,所以在CONVERT時,資料就有問題了(請看下面FLOAT_2_VARCHAR_VALUE的值)。

以下為FLOAT的CONVERT SQL,


SELECT CAST(1000039 AS FLOAT) AS FLOAT_VALUE
SELECT CAST(CAST(1000039 AS FLOAT) AS VARCHAR) AS FLOAT_2_VARCHAR_VALUE
SELECT CAST(CAST(CAST(1000039 AS FLOAT) AS VARCHAR) AS FLOAT) AS FLOAT_2_VARCHAR_2_FLOAT_VALUE

 

 

image

 

所以使用金額請使用精確數值的資料型態,如DECIMAL等。別再用近似數值的資料型態,如FLOAT、REAL。

以下為DECIMAL的CONVERT SQL,


SELECT CAST(1000039 AS DECIMAL) AS DECIMAL_VALUE
SELECT CAST(CAST(1000039 AS DECIMAL) AS VARCHAR) AS DECIMAL_2_VARCHAR_VALUE
SELECT CAST(CAST(CAST(1000039 AS DECIMAL) AS VARCHAR) AS DECIMAL) AS DECIMAL_2_VARCHAR_2DECIMAL_VALUE

 

 

image

 

參考資料:資料類型 (Transact-SQL)

如果存放顯示只會到小數2位的話,建議使用money
如搭果有超過小數2位以上的話,又配資料庫加/解密去做convert成varchar的話,
那可以改使用decimal去指定小數位數,如下,


--指定總位數為18,小數位數可放3位
DECLARE @defaultDECIMAL DECIMAL(18, 3);
SELECT @defaultDECIMAL = 1000039.123
SELECT @defaultDECIMAL
SELECT CAST(@defaultDECIMAL AS VARCHAR) AS DECIMAL_2_VARCHAR_VALUE
SELECT CAST(CAST(@defaultDECIMAL AS VARCHAR) AS DECIMAL(18, 3)) AS DECIMAL_2_VARCHAR_2_DECIMAL_VALUE

 

如果還是使用money的話,那在convert時,就改用STR函數去指定轉換的小數位數,如下,


DECLARE @defaultMONEY MONEY;
SELECT @defaultMONEY = 1000039.1234
SELECT @defaultMONEY;
SELECT CAST(@defaultMONEY AS VARCHAR(53)) AS MONEY_2_VARCHAR_VALUE
SELECT CAST(CAST(@defaultMONEY AS VARCHAR) AS MONEY) AS MONEY_2_VARCHAR_2_MONEY_VALUE
SELECT LTRIM(STR(@defaultMONEY,18 , 4)) AS MONEY_2_STR_VALUE
SELECT CAST( LTRIM(STR(@defaultMONEY,18 , 4)) AS MONEY) AS MONEY_2_VARCHAR_2_MONEY_VALUE

 

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^