MySQL 从 MS.NET 批量插入关系 table

MySQL Bulk Insert for relational table from MS.NET

我想使用 C# 执行从 CSV 到 MySQL 数据库的批量插入,我正在使用 MySql.Data.MySqlClient 进行连接。 CSV 列被引用到多个表中,它们依赖于主键值,例如,

CSV(列和值):-

emp_name, address,country
-------------------------------
jhon,new york,usa
amanda,san diago,usa
Brad,london,uk

DB 架构(CountryTbl)和值

country_Id,Country_Name
1,usa
2,UK
3,Germany

数据库模式(EmployeeTbl)

Emp_Id(AutoIncrement),Emp_Name

数据库模式(地址表)

Address_Id(AutoIncrement), Emp_Id,Address,countryid

问题陈述:

1> 从 CSV 中读取数据以从 "CountryTbl" 中获取相应员工的 CountryId。

2> 将数据插入 EmployeeTbl 和 AddressTbl with CountryId

方法一

按照上述问题陈述步骤进行,但这会影响性能(逐行读取和插入)

方法二

使用 "Bulk Insert" 选项“MySqlBulkLoader”,但这需要读取 csv 文件,看起来这个选项对我不起作用。

方法 3

使用存储过程并使用上传过程。但是我不想使用存储过程。

如果有任何其他选项可以批量上传或建议任何其他方法,请提出建议。

除非您要上传数十万行,否则批量加载(您的方法 2)可能不值得花费额外的编程和调试时间。这是我的看法,物有所值(是您为此付出的两倍:)

方法 1 和 3 大致相同。区别在于您是从 c# 还是从 sp 发出查询。您仍然需要计算出查询。那么让我们来处理 1.

这类问题的解决方案取决于 RDBMS 的品牌和型号。如果您决定要迁移到 SQL 服务器,则必须更改这些内容。

这就是你要做的。对于您的员工 csv 的每一行 ...

...将一行放入员工表

 INSERT INTO EmployeeTbl (Emp_Name) VALUES (@emp_name);

请注意,此查询使用插入查询的 INSERT ... VALUES 形式。当此查询(或任何插入查询)运行时,它会删除自动递增的 Emp_Id 值,随后调用 LAST_INSERT_ID() 可以获得它。

... 将一行放入地址table

INSERT INTO AddressTbl (Emp_Id,Address,countryid)
     SELECT LAST_INSERT_ID() AS Emp_Id, 
            @address AS Address, 
            country_id AS countryid
       FROM CountryTbl
      WHERE Country_Name = @country;

请注意,第二个 INSERT 使用插入查询的 INSERT ... SELECT 形式。所有这些的 SELECT 部分生成一行数据,其中包含要插入的列值。

  • 它使用LAST_INSERT_ID()得到Emp_Id,
  • 它使用您的 C# 程序为 @address
  • 提供的常量
  • 它从您先前存在的 CountryTbl 中查找 countryid 值。

当然,请注意,您必须使用 the C# Parameters.AddWithValue() method 来设置这些查询中 @ 参数的值。这些值来自您的 CSV 文件。

最后,将每千行左右的 csv 包装在 transaction 中,方法是在它们的 INSERT 语句之前加上 START TRANSACTION; 语句并以 COMMIT; 语句结束它们。这将使您的性能得到提升,如果出现问题,整个事务将被回滚,以便您可以重新开始。