将NVARCHAR转换为DECIMAL时小数全部丢失的问题排查
问题:NVARCHAR转DECIMAL时小数位全部丢失
我通过BULK INSERT将CSV文件数据加载至所有列类型为NVARCHAR(100)的临时表Stage_factFinanzbuchhaltung,此步骤执行正常。后续计划将数据插入生产表factFinanzbuchhaltung并转换数据类型,但在将含数值的列从NVARCHAR转换为DECIMAL时,所有小数均丢失。
以下是创建生产表并从临时表插入数据的代码:
DROP TABLE IF EXISTS [dbo].[factFinanzbuchhaltung] GO CREATE TABLE [dbo].[factFinanzbuchhaltung] ( Wert DECIMAL ) GO INSERT INTO [dbo].[factFinanzbuchhaltung] SELECT CONVERT(DECIMAL(25, 2), ROUND(Wert,2)) FROM [dbo].[Stage_factFinanzbuchhaltung]
尝试过CONVERT、CAST的各种组合,以及带或不带ROUND的写法,问题依旧。
解决方案
核心问题:生产表字段未指定小数位数
你创建生产表时,Wert字段仅定义为DECIMAL,未指定精度和小数位数。SQL Server中DECIMAL的默认设置是DECIMAL(18,0)——即整数位最多18位,小数位0位。这意味着即使你在SELECT里转换为DECIMAL(25,2),插入到表时还是会被自动截断为整数,这就是小数丢失的直接原因。
修正步骤:
- 修改生产表的字段定义,明确指定精度和小数位数,与转换时的参数匹配:
DROP TABLE IF EXISTS [dbo].[factFinanzbuchhaltung] GO CREATE TABLE [dbo].[factFinanzbuchhaltung] ( Wert DECIMAL(25, 2) -- 明确指定25位精度、2位小数 ) GO INSERT INTO [dbo].[factFinanzbuchhaltung] SELECT CONVERT(DECIMAL(25, 2), Wert) -- 若CSV数据本身是正确的小数格式,无需额外ROUND FROM [dbo].[Stage_factFinanzbuchhaltung]
- 额外排查:CSV数据的小数分隔符问题
如果修改表定义后仍有问题,检查CSV中的数值格式:若你的CSV使用逗号作为小数分隔符(比如欧洲格式的1,99而非1.99),SQL Server会将其识别为千位分隔符,转换时直接截断小数部分。此时需要先替换分隔符再转换:
INSERT INTO [dbo].[factFinanzbuchhaltung] SELECT CONVERT(DECIMAL(25, 2), REPLACE(Wert, ',', '.')) FROM [dbo].[Stage_factFinanzbuchhaltung]
内容的提问来源于stack exchange,提问作者jayjay
相关产品推荐
相关产品推荐

