存儲過程中 CAST(32.678 AS DECIMAL(5,1)) 產生 32.7,測試人員以為未四捨五入,實則 CAST/CONVERT 轉換至定點數型別時會四捨五入,非單純截斷。
SELECT ROUND(32.678, 1); -- 32.700 (保留小數位數由精度決定) SELECT CAST(32.678 AS DECIMAL(5,1)); -- 32.7 SELECT CONVERT(NUMERIC(5,1), 32.678); -- 32.7
結論:三者結果一致,皆為四捨五入,非截斷。
ROUND(numeric_expression, length [, function])
length > 0:保留小數點右側位數。length < 0:小數點左側捨入 (十位、百位...)。function = 0 (預設):四捨五入。function <> 0:截斷 (Truncate)。-- 正數 length SELECT ROUND(123.4545, 2); -- 123.4500 SELECT ROUND(123.4555, 2); -- 123.4600 -- 負數 length (左側捨入) SELECT ROUND(748.58, -1); -- 750.00 SELECT ROUND(748.58, -2); -- 700.00 SELECT ROUND(748.58, -3); -- 1000.00 SELECT ROUND(748.58, -4); -- 0.00 (超過最高位) -- function 參數 SELECT ROUND(150.75, 0); -- 151.00 (四捨五入) SELECT ROUND(150.75, 0, 1); -- 150.00 (截斷)
SELECT CAST('123.456' AS DECIMAL); -- 123 (預設 precision=18, scale=0 → 四捨五入到整數)
SELECT CAST('123.456' AS DECIMAL(38,2)); -- 123.46 (保留 2 位小數,四捨五入)
關鍵:DECIMAL(p,s) / NUMERIC(p,s) 轉換時,自動四捨五入到指定小數位數 s。
SELECT ROUND(123.75633, 2, 1); -- 123.75000 (先截斷到 2 位再補 0) SELECT ROUND(123.75633, 2); -- 123.76000 (直接四捨五入到 2 位)
function=1 導致「截斷後補零」,非數學意義上的四捨五入,報表計算慎用。
DECIMAL(18,6) 等),應用層/報表工具負責顯示格式 (FORMAT, ToString("N2"))。DECIMAL/NUMERIC 固定精度,避免 FLOAT/REAL 二進制誤差。ROUND(val, n, 1) 或 FLOOR(val * POWER(10,n)) / POWER(10,n)。WHERE DecimalCol = '123.45' 導致索引失效,參數化傳遞正確型別。ROUND、CAST、CONVERT 在轉換定點數時預設皆為四捨五入。ROUND 提供 function 參數控制截斷/捨入方向及負數位數捨入,功能最完整。財務/精度敏感系統務必在資料庫層面定義固定精度欄位,格式化交由表現層處理。