2010-11-01 71 views
0

我有一个文本文件,其中包含自定义格式的数据库表转储记录,该文本在特定位置具有标识操作记录的字符:将文本文件导入数据库的最快方法

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

因此,如果我发现在文本文件中我需要删除记录到数据库中的d的记录,而不是如果我找到一个M的记录,我需要插入该记录如果不存在于数据库中,如果已经存在我需要起来约会。

什么是更好和最快的方式来导入一个类似的文本文件在数据库表中使用.NET Framework和C#? 我在这个文本文件中有30万条平均记录。

感谢

+0

数据库中有多少条记录需要匹配? – 2010-11-01 19:00:18

+3

什么数据库服务器? – dotariel 2010-11-01 19:00:28

+0

您正在使用ORM还是正在编写裸露的SQL语句? – 2010-11-01 19:04:40

回答

2

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

最快的方法可能是创建一个批量SQL脚本来执行。在选择数据时,LinQ可以为您节省大量时间(您可能会随时对其进行转换)。

还有一些应该考虑的平台特定解决方案。请参阅此处的SQLServer批量插入。

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

1

为什么不分析文本和生成插入,更新和删除语句然后只需运行你生成的脚本?

+1

我还会在特定的时间间隔内添加一些提交以加快速度。 – 2010-11-01 19:13:31

+0

如何确定SQL语句是插入还是更新?我是否需要查询目标表以了解记录是否已经存在或不存在? – aleroot 2010-11-02 07:02:24

+0

@aleroot - 再次阅读您的问题。我没有意识到你使用M来插入和更新。由于记录可能全部不同,因此可以在SQL脚本中尝试一下。如果发现异常并且错误是记录已经存在,请在catch中进行更新。虽然不是超级优雅。如果你可以做一个IF EXISTS,而这个记录是独一无二的,但是我有一种感觉,你不会知道每个记录的主键是什么。 – nickytonline 2010-11-02 20:40:22

0

有没有简单的方法来做到这一点,你要不管是什么,以确定你需要运行什么SQL语句分析文本。你必须自己决定它是否是一个更新或插入语句,希望你可以批量操作,否则每次你点击一个“M”时碰到数据库往往不会是一个好主意。

0

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

将文件的内容插入到登陆表后,可以执行一系列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 

链接,我做一个快速搜索后发现:

+0

Woops!我注意到原始问题提到使用“M”来表示插入和更新,而我的代码示例假设“I”为插入,“U”为更新。修改示例以使用“M”应该很简单。 – 2010-11-01 22:04:14

0

插入临时表然后JOIN更新或删除。

相关问题