导入以分号分隔的CSV文件

时间:2019-05-09 07:36:23

标签: c# sql-server tsql

我有一个从燃油供应商门户网站下载的CSV文件。数据以分号分隔,在具有字段标题的行之前有11行注释。

enter image description here

有3行摘要,并且是Unix LF编码

enter image description here

我使用SQL命令BULK INSERT从另一个供应商处导入另一个数据文件:-

BULK INSERT [dbo].[fuel_stagingShell]
FROM '\\server\path\dataimports\fueldata\Shell\results.csv'
WITH
(
    FORMAT = 'CSV',
    FIELDQUOTE ='"',
    FIRSTROW=2,
    FIELDTERMINATOR = ',',
    ROWTERMINATOR='\n',
    TABLOCK
)

这很完美,因为它可以瞬间导入文件。

但是,当我尝试批量插入时,该文件将无法使用。是的,我可以通过更改FIRSTROW来跳过标题行,但是文件末尾存在三行的问题。 BULK INSERT命令上的LASTROW参数需要一个行号,由于文件的长度可变,我不知道该行号。

我当时想用C#导入文件,跳过第11行中的第1行,直到到达以“ Total;”开头的行时终止。并根据标题名称匹配列。

有没有一种方法可以导入数据行,并将其拆分为数组/ POCO /其他东西,如果您知道数据的可用性,那真的是一种简单明了的方法吗?

我还从供应商那里获得了另一个文件,该文件的格式相同,只是缺少六个字段。这就是为什么我一直认为通过匹配列名来进行填充,但是我知道填充每一行中的每个属性可能比其他未知方法慢很多。

编辑:我复制了该问题,以便可以编辑该帖子,并遇到与文件相关的错误,并且此人得到的错误消息为("IID_IColumnsInfo") error with SQL Server BULK INSERT of CSV file,所以我如注释中的@steve所示,将\ n替换为0x0a并添加了一个任意的LASTROW参数,当我注释掉FIELDQUOTE参数时,它导入了一行行。

我现在正在考虑可以预先准备文件并计算有多少行,然后从我的应用程序将其构建到动态SQL中。或者,用更长的varchar字段修改我的登台表,该字段将接受文件末尾的所有注释位,并在T-SQL存储过程中忽略它们,以验证数据并将其转换为事务表。

这是我使用的T-SQL:

BULK INSERT [dbo].[fuel_stagingDkv]
FROM '\\server\path\dataimports\fueldata\DKV\Results.csv'
WITH
(
FORMAT = 'CSV',
--FIELDQUOTE ='',
FIRSTROW=12,
LASTROW=5000,
FIELDTERMINATOR = ';',
ROWTERMINATOR='0x0a',
TABLOCK
)

1 个答案:

答案 0 :(得分:0)

如果您知道需要在底部跳过一定数量的文件,并且可以启用xp_cmdshell来获取文件的行数,则可以执行以下操作:

USE tempdb
GO

DECLARE 
    @filePath nvarchar(max) = '\\server\path\dataimports\fueldata\DKV\Results.csv'

DECLARE 
    @cmd nvarchar(1000) = 'type "' + @filePath + '" | find /c /v ""'
    ,@lastRow int

DECLARE @Output TABLE (
    Id int IDENTITY(1, 1)
    ,CmdOutput nvarchar(300)
)
INSERT INTO @Output ( CmdOutput )
EXEC xp_cmdshell @cmd

SELECT TOP 1 @lastRow = CmdOutput
FROM @Output 
WHERE
    CmdOutput IS NOT NULL 
ORDER BY
    Id DESC


BULK INSERT [dbo].[fuel_stagingDkv]
FROM '\\server\path\dataimports\fueldata\DKV\Results.csv'
WITH
(
FORMAT = 'CSV',
--FIELDQUOTE ='',
FIRSTROW=12,
LASTROW=@lastRow,
FIELDTERMINATOR = ';',
ROWTERMINATOR='0x0a',
TABLOCK
)

或者,您也许可以使用xp_cmdshell创建不带第一行和最后一行的新文件。

相关问题