SQL Server BULK INSERT导入CSV时FIELDQUOTE双引号未生效
BULK INSERT的FIELDQUOTE参数不生效问题排查
核心原因
FIELDQUOTE是SQL Server 2017(14.x)及以上版本才新增的导入参数,是否生效和你使用的SSMS V18.10客户端版本无关,只和你连接的数据库引擎实例版本有关:
- 如果实例版本低于2017,书写FIELDQUOTE不会抛出语法错误,但参数会被直接忽略,不会自动处理字段包裹的双引号
- 如果实例版本是2017及以上,绝大多数不生效问题是漏写了必填的
FORMAT = 'CSV'参数——FIELDQUOTE是CSV格式导入专属参数,不指定FORMAT为CSV时参数不会被加载 - 少数情况是动态SQL拼接时引号转义错误,导致FIELDQUOTE实际传入空值
修复步骤
- 先确认数据库引擎版本,在SSMS中执行以下语句查看版本信息:
SELECT @@VERSION
- 如果版本低于2017,直接放弃FIELDQUOTE参数,采用导入后清理的方案:
- 保留现有导入逻辑,所有数据导入完成后,写动态SQL遍历所有导入生成的业务表,对每个NVARCHAR类型字段执行去引号操作:
-- 单表去引号示例逻辑,批量执行时动态替换表名、列名即可 UPDATE 目标表 SET 列1 = TRIM('"' FROM 列1), 列2 = TRIM('"' FROM 列2)- 建表阶段拆分表头时,同步去掉每个列名首尾包裹的双引号,避免生成的列名带多余符号。
- 如果版本为2017及以上,按以下要求修改脚本:
- 两处BULK INSERT的WITH子句中,新增
FORMAT = 'CSV'参数 - 确认@FieldQuote的赋值正确,避免动态SQL拼接时引号截断:
DECLARE @FieldQuote NVARCHAR(5) = '"'- 修正后数据导入部分的BULK INSERT语法示例:
注意读取表头的那部分BULK INSERT也要同步加上FORMAT='CSV'参数,否则表头的双引号也不会被处理。SET @SQL = ' BULK INSERT [dbo].[' + @TableName + '] FROM ''' + @Path + @FileName + ''' WITH ( FORMAT = ''CSV'', FIRSTROW = 2, MAXERRORS = 0, FIELDTERMINATOR = ''' + @ColumnTerminator + ''', ROWTERMINATOR = ''' + @RowTerminator + ''', FIELDQUOTE = ''' + @FieldQuote + ''' )' - 两处BULK INSERT的WITH子句中,新增
建表逻辑优化
原脚本拆分表头时没有处理列名包裹的双引号,建议修改拆分逻辑,自动清理列名的多余引号:
WHILE CHARINDEX(@ColumnTerminator, @Header) > 0 BEGIN DECLARE @SingleCol NVARCHAR(255) = LTRIM(RTRIM(SUBSTRING(@Header, 1, CHARINDEX(@ColumnTerminator, @Header) - 1))) SET @SingleCol = TRIM('"' FROM @SingleCol) -- 去除列名首尾双引号 SET @CreateHeader = @CreateHeader + '[' + @SingleCol + '] NVARCHAR(255), ' SET @Header = SUBSTRING(@Header, CHARINDEX(@ColumnTerminator, @Header) + 1, LEN(@Header)) END SET @Header = TRIM('"' FROM @Header) -- 处理最后一个列名的引号 SET @CreateHeader = @CreateHeader + '[' + @Header + '] NVARCHAR(255)'
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

