You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server导入smallmoney类型数据时转换错误求助

解决CSV导入SQL Server时smallmoney列带$符号的转换错误

这个问题我之前帮团队处理过好几次,核心原因很明确:SQL Server的smallmoney类型默认不识别带$前缀的数值,批量导入时会把$当成非法字符,直接抛出类型不匹配的错误(也就是你遇到的Msg 4864)。给你三个实用的解决思路,按需选择:

1. 预处理CSV,批量移除$符号

最简单直接的方式就是先清理CSV文件里的$符号。如果是手动处理,用Excel打开CSV,选中BillingRate列,用查找替换功能把$替换为空就行;如果是需要自动化处理,用PowerShell脚本几行就能搞定:

# 读取原CSV,移除所有$符号后保存为新文件
(Get-Content "D:\data\your_data.csv") -replace '\$', '' | Set-Content "D:\data\cleaned_data.csv"

处理后的CSV里BillingRate列就变成纯数字格式(比如203.75),再导入就不会触发类型错误了。

2. 通过临时表中转,导入后再转换数据

如果不方便修改原CSV文件,可以先把数据导入到一个临时表(把BillingRate设为varchar类型),然后再清理字符并转换为smallmoney插入正式表。这种方式灵活性很高,就算数据里还有其他格式问题(比如千分位逗号)也能一并处理:

-- 创建临时导入表,所有列用字符串类型兼容CSV格式
CREATE TABLE #TempBillingData (
    ID VARCHAR(50),
    EmployeeName VARCHAR(100),
    Department VARCHAR(50),
    BillingRate VARCHAR(20)
);

-- 批量导入CSV到临时表
BULK INSERT #TempBillingData
FROM 'D:\data\your_data.csv'
WITH (
    FIRSTROW = 2, -- 如果CSV第一行是表头就设为2,否则设为1
    FIELDTERMINATOR = ',', -- CSV的列分隔符,根据你的文件调整
    ROWTERMINATOR = '\r\n'
);

-- 清理数据并插入正式表
INSERT INTO Your正式表 (ID, EmployeeName, Department, BillingRate)
SELECT 
    ID,
    EmployeeName,
    Department,
    -- 先移除$和可能的千分位逗号,再转换为smallmoney
    CAST(REPLACE(REPLACE(BillingRate, '$', ''), ',', '') AS SMALLMONEY) AS BillingRate
FROM #TempBillingData;

-- 清理临时表
DROP TABLE #TempBillingData;

3. 使用格式文件(Format File)指定列处理规则

如果是频繁的批量导入场景,可以创建一个XML格式文件,告诉SQL Server如何解析带$的BillingRate列。举个适配你场景的格式文件示例(假设你的表有4列,第4列是BillingRate):

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID="1" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="50"/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="100"/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="50"/>
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="20"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="ID" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="2" NAME="EmployeeName" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="3" NAME="Department" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="4" NAME="BillingRate" xsi:type="SQLSMALLMONEY"/>
 </ROW>
</BCPFORMAT>

然后在BULK INSERT时指定这个格式文件:

BULK INSERT Your正式表
FROM 'D:\data\your_data.csv'
WITH (
    FORMATFILE = 'D:\data\billing_format.xml',
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '\r\n'
);

额外提醒

如果你的CSV里金额还带有千分位逗号(比如$1,203.75),记得在转换前先移除逗号,不然同样会触发转换错误,就像上面临时表方法里写的那样用两次REPLACE处理。

内容的提问来源于stack exchange,提问作者Thomas Mutton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:12:04