我有一个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中,只需插入一次(如批量)并且不使用循环,但我不知道是否可能。
提前感谢!
答案 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中的内容。
请注意,删除的列只是从显示中删除,而不是数据表。数据库将设置Id
,LastUpdated
列上有一个触发器(从另一个答案留下),因此不需要显示这些列。
获取数据
为此,我导入了一些我生成的假数据。将数据添加到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)
此命令插入多行。