在SQL Server中使用CSV文件进行BULK INSERT

时间:2014-04-12 05:28:33

标签: sql sql-server csv

我有一个包含10000行的.CSV文件。需要将这些行插入/更新到SQL Server数据库表中。

可能存在这样的情况:数据库中可能存在几行,这意味着需要更新这些行并在日志文件中触发。如果数据库中不存在,则需要插入。

一种可能的解决方案是,我可以逐行阅读,检查数据库中的条目并相应地构建插入/更新查询。但是,此过程可能需要很长时间来创建更新/插入查询并在数据库中执行它们。有时我的CSV文件可能有数百万条记录。

有没有其他更快的方法来实现此功能?

以下是我试图实现的代码。在这篇文章中,我将使用BULK INSERT语句进行批量导入。我们使用BULK INSERTMERGE语句,因为此实现不仅用于插入记录,还用于更新记录(如果已存在)。

BULK INSERT tablename
FROM 'D:\xmlData\Trialbalelce.txt' --This is CSV file
WITH ( FIELDTERMINATOR =',',rowterminator = '\n',FIRSTROW = 1 )

1 个答案:

答案 0 :(得分:11)

好的,希望这一切都有帮助。我把您在评论中发布的内容转换为存储过程。方案是您有一个具有一致格式的平面文件,您每次都会将其加载到同一个表中(dbo.custCompInfo_Tab)。该表将合并到dbo.Daily_Sync上匹配的最终目标(CompanyName)。我添加了一些数据列来进一步说明合并。

<强> SETUP:

CREATE TABLE dbo.Daily_Sync
    (CompanyName VARCHAR(10)
   , UserId INT
   , col1 INT
   , col2 INT
   , col3 INT
    )

CREATE TABLE dbo.custCompInfo_Tab
    (CompanyName VARCHAR(10)
   , col1 INT
   , col2 INT
   , col3 INT
    )

我要加载两个数据文件,TrialBalance.txt和TrialBalance2.txt。它们包含以下数据:

TrialBalance.txt

abc,1,2,3
def,4,5,6
qwe,7,8,9
asd,10,11,12
zxc,13,14,15

TrialBalance2.txt

abc,1,2,3
def,20,21,22
qwe,7,8,9
xcv,10,11,12
xbv,13,14,15

我创建了一个截断登台表的存储过程,使用传入的文件路径中的数据加载表,然后将其合并到目标中。

CREATE PROCEDURE dbo.loadDailyData
    @FullFilePath NVARCHAR(MAX)
AS 
    BEGIN
        DECLARE @sql NVARCHAR(MAX)  
    TRUNCATE TABLE dbo.custCompInfo_Tab

    SET @sql = N'BULK INSERT dbo.custCompInfo_Tab FROM ''' + @FullFilePath
        + ''' WITH ( FIELDTERMINATOR ='','',ROWTERMINATOR = ''\n'',FIRSTROW = 1 )'

    SELECT  @sql

    EXEC sp_executesql @sql

    MERGE INTO dbo.Daily_Sync AS TGT
        USING 
            (SELECT CompanyName
                  , USER_ID() usrid
                  , col1
                  , col2
                  , col3
             FROM   dbo.custCompInfo_Tab
            ) AS SRC
        ON TGT.Companyname = SRC.CompanyName
        WHEN MATCHED 
            THEN UPDATE
                SET     TGT.Companyname = SRC.companyname
                      , TGT.col1 = SRC.col1
                      , TGT.col2 = SRC.col2
                      , TGT.col3 = SRC.col3
        WHEN NOT MATCHED 
            THEN INSERT (companyname
                       , UserId
                       , col1
                       , col2
                       , col3
                        )
                VALUES  (SRC.CompanyName
                       , SRC.usrid
                       , SRC.col1
                       , SRC.col2
                       , SRC.col3
                        ); 

END

这里有动态sql用于构建字符串而不是行数,BULK INSERT字符串就是返回的所有字符串。

最后,我们可以看到之前和之后的表格:

SELECT  *
FROM    dbo.custCompInfo_Tab
SELECT  *
FROM    dbo.Daily_Sync

EXEC dbo.loadDailyData @FullFilePath = 'D:\xmlData\TrialBalance.txt'


SELECT  *
FROM    dbo.custCompInfo_Tab
SELECT  *
FROM    dbo.Daily_Sync

EXEC dbo.loadDailyData @FullFilePath = 'D:\xmlData\TrialBalance2.txt'


SELECT  *
FROM    dbo.custCompInfo_Tab
SELECT  *
FROM    dbo.Daily_Sync

<强>结果:

enter image description here