SQL批量导入文件夹内CSV文件到现有表报错如何解决?
问题根因
从报错信息可以看出,你调用xp_cmdshell执行dir命令后返回的结果不止包含CSV文件名,还混入了磁盘卷标、序列号、目录说明、错误提示等无效内容,这些内容被误当作文件名拼接进了BULK INSERT语句,导致找不到对应文件。具体错误点有两个:
- dir命令的拼接逻辑错误,引号位置不对,没有正确触发纯文件名输出规则,额外返回了很多系统信息
- 没有对
xp_cmdshell返回的结果做过滤,空行、错误提示等无效内容都被插入到了文件名列表中
修改后的完整代码
DECLARE @ALLFILENAMES TABLE (WHICHPATH VARCHAR(255),WHICHFILE varchar(255)) declare @filename varchar(255), @path varchar(255), @sql varchar(8000), @cmd varchar(1000) --get list of files to process SET @path = 'C:\Invoices\IGG_Data_StoreNum\X05\' -- 修正dir命令:路径加双引号,/b返回纯文件名,/a-d排除子目录 SET @cmd = 'dir "' + @path + '*.csv" /b /a-d' INSERT INTO @ALLFILENAMES(WHICHFILE) EXEC Master..xp_cmdShell @cmd UPDATE @ALLFILENAMES SET WHICHPATH = @path where WHICHPATH is null -- 过滤无效行:空值、非CSV文件、系统提示行 DELETE FROM @ALLFILENAMES WHERE WHICHFILE IS NULL OR WHICHFILE NOT LIKE '%.csv' OR WHICHFILE LIKE 'Volume%' OR WHICHFILE LIKE 'Directory%' OR WHICHFILE LIKE 'File Not Found%' OR WHICHFILE LIKE 'Serial Number%' SELECT * FROM @ALLFILENAMES --cursor loop declare c1 cursor for SELECT WHICHPATH,WHICHFILE FROM @ALLFILENAMES open c1 fetch next from c1 into @path,@filename While @@fetch_status <> -1 begin -- 文件名非空才执行插入 IF @filename IS NOT NULL AND @filename <> '' BEGIN --make a query and execute set @sql = 'BULK INSERT [SVTTASKS].[dbo].[OOS_AWG_X05] FROM ''' + @path + @filename + ''' ' + ' WITH (firstrow = 2, fieldterminator = '','', rowterminator=''\n'')' print @sql exec (@sql) END fetch next from c1 into @path,@filename end close c1 deallocate c1
额外注意事项
- 如果执行后仍然提示找不到文件,先手动确认
C:\Invoices\IGG_Data_StoreNum\X05\路径下确实存在后缀为.csv的文件 - 确保你使用的SQL Server账号有执行
xp_cmdshell的权限,且SQL Server服务的运行账号对目标CSV文件夹有读取权限 - 如果CSV文件包含中文或者特殊字符,可尝试在BULK INSERT的WITH参数中添加
CODEPAGE = '65001'(UTF8编码)或者CODEPAGE = '936'(GBK编码)避免乱码
内容的提问来源于stack exchange,提问作者Anthony Bondi
相关产品推荐
相关产品推荐

