代码之家  ›  专栏  ›  技术社区  ›  aleroot

将文本文件导入数据库的最快方法

  •  0
  • aleroot  · 技术社区  · 14 年前

    我有一个文本文件,其中包含一个自定义格式的数据库表转储记录,此文本在特定位置有一个字符,该字符用该记录标识操作:

    • M=插入或更新
    • D=删除记录

    因此,如果在文本文件中找到D记录,我需要将记录删除到数据库中,相反,如果我发现M记录,如果数据库中不存在,则需要插入记录,如果已经存在,我需要更新它。

    使用.NET Framework和c#在数据库表中导入类似文本文件的最佳和最快方法是什么? 我在这个文本文件中平均有300000条记录。

    谢谢

    5 回复  |  直到 14 年前
        1
  •  2
  •   Falcon    14 年前

    最简单的方法可能是使用ADO.NET创建一个类型化的datatable,将数据加载到其中并相应地设置datarowstate,然后通过DataAdapter刷新数据。

    最快的方法可能是创建一个要执行的大容量SQL脚本。在选择数据时,LinQ可以为您节省很多时间(您可能可以动态转换它)。

    还应该考虑特定于平台的解决方案。请参阅此处的SQLServer大容量插入。

    http://dotnetslackers.com/Community/blogs/xun/archive/2008/04/15/sql-bulk-insert-and-ado-net-sqlbulkcopy.aspx

        2
  •  1
  •   nickytonline    14 年前

    为什么不解析文本并生成insert、update和delete语句,然后运行生成的脚本呢?

        3
  •  0
  •   Tyug    14 年前

    要做到这一点并不是一个简单的方法,您将不得不解析文本,而不管您需要运行什么样的SQL语句。您必须自己决定它是update还是insert语句,希望您可以进行批处理,否则每次点击“M”时都要点击数据库并不是一个好主意。

        4
  •  0
  •   Dr. Wily's Apprentice    14 年前

    如果您使用的是SQL Server,则可以利用 Bulk Insert functionality . 这应该是将文件中的数据插入数据库的最快方式。我要做的第一件事是将文件中的数据插入到“登录表”(即结构与文件结构匹配的表)中。另请注意: .NET 2.0 introduced SqlBulkCopy ,如果您已经将数据存储在内存中,或者正在使用某种数据读取器读取数据,则此功能也同样有用。

    一旦文件的内容插入到登录表中,就可以执行一系列SQL语句,将登录表合并到目标表中。下面是这些SQL语句的示例实现(免责声明:我没有检查这些语句的正确性):

    DELETE FROM MyTable
    WHERE EXISTS (
        SELECT 1
        FROM LandingTable
        WHERE
            LandingTable.RecordType = 'D'
            AND LandingTable.KeyField1 = MyTable.KeyField1
            AND LandingTable.KeyField2 = MyTable.KeyField2
    
    
    UPDATE MyTable SET
        MyTable.Field1 = LandingTable.Field1,
        MyTable.Field2 = LandingTable.Field2,
        -- ...
    FROM MyTable
    INNER JOIN LandingTable ON
        LandingTable.KeyField1 = MyTable.KeyField1
        AND LandingTable.KeyField2 = MyTable.KeyField2
    where
        LandingTable.RecordType = 'U'
    
    INSERT INTO MyTable (
        Field1,
        Field2,
        -- ...
    )
    SELECT
        LandingTable.Field1,
        LandingTable.Field2,
        -- ...
    FROM LandingTable
    WHERE
        LandingTable.RecordType = 'I'
    
    -- Consider how to handle "Insert" records where there is already a record in MyTable with the same key
    -- Possible solution below: treat as an "Update"
    UPDATE MyTable SET
        MyTable.Field1 = LandingTable.Field1,
        MyTable.Field2 = LandingTable.Field2,
        -- ...
    FROM MyTable
    INNER JOIN LandingTable ON
        LandingTable.KeyField1 = MyTable.KeyField1
        AND LandingTable.KeyField2 = MyTable.KeyField2
    where
        LandingTable.RecordType = 'I'
    
    -- Now only insert records from LandingTable where there is no corresponding record in MyTable with the same key (determined with a left outer join)
    INSERT INTO MyTable (
        Field1,
        Field2,
        -- ...
    )
    SELECT
        LandingTable.Field1,
        LandingTable.Field2,
        -- ...
    FROM LandingTable
    LEFT OUTER JOIN MyTable ON
        MyTable.KeyField1 = LandingTable.KeyField1
        AND MyTable.KeyField2 = LandingTable.KeyField2
    WHERE
        LandingTable.RecordType = 'I'
        and MyTable.KeyField1 is null
    

    快速搜索后找到的链接:

        5
  •  0
  •   THEn    14 年前

    插入临时表,然后连接以更新或删除。