将值从datagridview插入mysql数据库的最快方法是什么?

时间:2016-01-15 07:46:09

标签: mysql vb.net datagridview sql-insert bulkinsert

我有一个vb.net系统,我想从datagridview向mysql数据库插入10,000或更多记录。但是当我尝试这个时,它需要8分钟才能获得10,000条记录

For i As Integer = 0 To DataGridView1.Rows.Count - 1

                        Dim queryInsert As String = "INSERT INTO tbl_shipdetails (ship_date, item_type, item_code, imei1, imei2)" & _
                                                    "VALUES('" & DataGridView1.Rows(i).Cells(1).Value & "','" & DataGridView1.Rows(i).Cells(2).Value & "','" & DataGridView1.Rows(i).Cells(3).Value & "','" & DataGridView1.Rows(i).Cells(4).Value & "','" & DataGridView1.Rows(i).Cells(5).Value & "')"
                        MySqlCmd = New MySqlCommand
                        MySqlCmd.Connection = Myconnect
                        MySqlCmd.CommandText = queryInsert
                        MySqlCmd.ExecuteNonQuery()
                    Next

我想知道是否有人知道最快的方法是什么?谁能帮帮我吗。我正在考虑将datagridview中的整个值插入到mysql中,只需插入一次(如批量)并且不使用循环,但我不知道是否可能。

提前感谢!

3 个答案:

答案 0 :(得分:1)

我无法说明这会有多快,但是您的查询会有简单的优化

Dim queryInsert As String = "INSERT INTO tbl_shipdetails (ship_date, " & _
                             "item_type, item_code, imei1, imei2)" & _
                             "VALUES(@p1,'@p2,@p3,@p4,@p5)"
Dim cmd = New  MySqlCommand(queryInsert, Myconnect)
cmd.Parameters.Add("@p1", MySqlDbType.VarChar)
cmd.Parameters.Add("@p2", MySqlDbType.VarChar)    
cmd.Parameters.Add("@p3", MySqlDbType.VarChar)    
cmd.Parameters.Add("@p4", MySqlDbType.VarChar)    
cmd.Parameters.Add("@p5", MySqlDbType.VarChar)
For i As Integer = 0 To DataGridView1.Rows.Count - 1
    cmd.Parameters("@p1").Value = DataGridView1.Rows(i).Cells(1).Value
    cmd.Parameters("@p2").Value = DataGridView1.Rows(i).Cells(2).Value 
    cmd.Parameters("@p3").Value = DataGridView1.Rows(i).Cells(3).Value
    cmd.Parameters("@p4").Value = DataGridView1.Rows(i).Cells(4).Value
    cmd.Parameters("@p5").Value = DataGridView1.Rows(i).Cells(5).Value
    cmd.ExecuteNonQuery()
Next

使用参数允许您在循环外部一次构建MySqlCommand,并避免连接字符串所需的工作。 (更不用说Sql Injection的问题了)

请注意,我已经在sql文本中跟踪了您的提示,其中所有字段似乎都是字符串(VarChar)类型。如果您的字段具有不同的数据类型,那么您应该将MySqlDbType枚举调整为正确的数据类型(并转换输入值=

答案 1 :(得分:0)

注意: Steve的答案显示了创建SQL查询的正确方法,而不是将SQL与字符串串联。 没错。

但是,如果我想快速插入一堆行,我不希望重置参数值,也不想从DGV中删除值。我也不想花时间将数据放入 DGV。

不清楚数据的来源。鉴于大小,它听起来像一个导入操作,可能提供其他选项。但即使采用最初的方法,我认为还有其他问题,因为8分钟太长了。

在15秒内插入10,000个新行

我的表有1或2个列({Id,text(15),Int,Text(30),bool}),但这不会导致40倍的增加。此方法使用了几个提供程序工具:

' class level variables
Private dtDemo As DataTable
Private cbDemo As MySqlCommandBuilder
Private daDemo As MySqlDataAdapter

初始化它们:

Dim SQL = <sql>
              SELECT
                   Id, ItemName, ItemValue, Descr,
                   Active, LastUpdated
             FROM
                   simple
             WHERE
                   1 = 0
          </sql>.Value

Using dbcon = MySQLDB.GetMySQLConnection

    dbcon.Open()

    daDemo = New MySqlDataAdapter(SQL, dbcon)
    cbDemo = New MySqlCommandBuilder(daDemo)
    cbDemo.QuotePrefix = "`"
    cbDemo.QuoteSuffix = "`"
    daDemo.InsertCommand = cbDemo.GetInsertCommand()

    dtDemo = New DataTable
    daDemo.Fill(dtDemo)
End Using

dgv1.DataSource = dtDemo
dgv1.Columns.RemoveAt(0)               ' remove ID from display
dgv1.Columns.RemoveAt(dgv1.Columns.Count - 1)  ' remove LastUpdated 

WHERE子句创建一个没有行的表,只创建CommandBuilder构建各种命令所需的元数据。它在填充时会/将显示DGV中的内容。

请注意,删除的列只是从显示中删除,而不是数据表。数据库将设置IdLastUpdated列上有一个触发器(从另一个答案留下),因此不需要显示这些列。

获取数据

为此,我导入了一些我生成的假数据。将数据添加到DataTable而不是 DataGridView

Dim csvFile As String = "C:\Temp\mysqlbatch.csv"

Dim lines = File.ReadAllLines(csvFile)

Dim dr As DataRow
For Each s As String In lines
    ' not the best way to parse a csv
    Dim data = s.Split(","c)
    dr = dtDemo.NewRow        ' create new row with all the Cols
    dr("ItemName") = Data(0)
    dr("ItemValue") = Convert.ToInt32(Data(1))
    dr("Descr") = Data(2)
    dr("Active") = If(Convert.ToInt32(data(3)) = 0, False, True)
    dtDemo.Rows.Add(dr)
Next

完成此操作(几秒钟)后,数据将显示在DGV中。我想用户可能会编辑或修复数据吗?

插入数据

DataAdapter知道如何插入(从设置中),DataTable已经有数据,它知道哪些行是新的(所有行)。所以让他们整理出来:

Dim sw As New Stopwatch
sw.Start()
Dim rows As Int32

Using dbcon = MySQLDB.GetMySQLConnection
    dbcon.Open()

    daDemo.InsertCommand.Connection = dbcon
    rows = daDemo.Update(dtDemo)
End Using

sw.Stop()
Console.WriteLine("Inserted {0} rows in {1}ms", rows, sw.ElapsedMilliseconds)
  
    

在10464ms中插入10000行
    在9419ms中插入10000行

  

注意:可能不需要显式创建更新/插入连接。没有它,我的工作就好了。

显然,MySqlDataAdapter保留连接字符串或连接对象,从创建它以供以后使用。并非所有DataAdapter都可以; OleDB要求您创建,打开和设置连接对象,如图所示。

答案 2 :(得分:0)

MySQL允许在单个插入命令中插入多个行集。 在以下格式中创建一个字符串:

INSERT INTO yourTable(c1,c2,c3)
VALUES (r1v1,r1v2,r1v3), (r2v1,r2v2,r2v3), (r3v1,r3v2,r3v3), . . . (rNv1,rNv2,rNv3)

此命令插入多行。