如何使用 XmlReader 将 xml 文档中的多行插入到 sql 服务器
How to insert multiple rows from xml document to sql server using XmlReader
当然,我用谷歌搜索了我的问题:"visual basic xml to sql how to insert many rows XmlReader"。我什至将 'many' 更改为 'multiple'.
到目前为止,我只能将 first 条目添加到我的数据库中。
我很高兴能够使用 XmlReader,因为我听说它非常高效。
我也很高兴能够使用参数,因为无论如何我都无法正确连接(是的,我喜欢优雅地编码 - 我不会在这里谈论我的衣服)。
我的VB.Net代码:
Imports System.Data.SqlClient
Imports System.Xml
Public Class Form1
Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
Dim xmlFile As String
Dim connectionString As String
Dim connection As SqlConnection
Dim command As SqlCommand
Dim ds As New DataSet
Dim reader As XmlReader
Dim sqlStatement As String
'Tag names inside xml document, will have to be inserted into table
Dim company As Integer
Dim name As String
Dim streetaddress As String
Dim city As String
Dim status As Char
connectionString = "this connection string works"
xmlFile = "MyXMLFile.xml"
connection = New SqlConnection(connectionString)
reader = XmlReader.Create(xmlFile, New XmlReaderSettings())
ds.ReadXml(reader)
Dim doc As New XmlDocument()
doc.Load(xmlFile)
Dim nodelist As XmlNodeList = doc.SelectNodes(".//siteelement/site")
For Each node As XmlElement In nodelist
Dim i As Integer
For i = 0 To ds.Tables(0).Rows.Count - 1
company = Convert.ToInt32(ds.Tables(0).Rows(i).Item(0))
name = ds.Tables(0).Rows(i).Item(1)
streetaddress = ds.Tables(0).Rows(i).Item(2)
city = ds.Tables(0).Rows(i).Item(3)
status = ds.Tables(0).Rows(i).Item(4)
sqlStatement = "INSERT INTO [dbo].[SITE] ([COMPANY], [NAME], [STREETADDRESS], [CITY], [STATUS])" &
"VALUES (@COMPANY, @NAME, @STREETADDRESS, @CITY, @STATUS)"
command = New SqlCommand(sqlStatement, connection)
command.Parameters.AddWithValue("@COMPANY", company)
command.Parameters.AddWithValue("@NAME", name)
command.Parameters.AddWithValue("@STREETADDRESS", streetaddress)
command.Parameters.AddWithValue("@CITY", city)
command.Parameters.AddWithValue("@STATUS", status)
Try
connection.Open()
Dim rowsAffected As Integer = command.ExecuteNonQuery()
MessageBox.Show(rowsAffected & " entries were inserted into Site table")
'Release the resources
command.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
'Execute the sql statement against the connection
command.ExecuteNonQuery()
Next
Next
connection.Close()
End Sub
End Class
我的 xml 文件是什么样的:
<?xml version="1.0" encoding="UTF-8"?>
<siteelement>
<site>
<company>1000</company>
<name>STORE #2336</name>
<streetAddress>123 London Calling</streetAddress>
<city>London</city>
<status>I</status>
</site>
<site>
<company>1001</company>
<name>STORE #2332</name>
<streetAddress>123 City of New Orleans</streetAddress>
<city>New Orleans</city>
<status>A</status>
</site>
<site>
<company>1002</company>
<name>STORE #2333</name>
<streetAddress>123 Bla bla bla</streetAddress>
<city>Somewhere</city>
<status>A</status>
</site>
</siteelement>
问题:如何让 reader 通读所有 xml 文档?我错过了什么?哪里不对?
任何帮助将不胜感激。请注意我是 Visual Basic 的新手(不到一周!),如果您认为我可以改进我的代码...
提前致谢。
在循环的第一次迭代中,您将打开 SqlConnection
,但永远不会关闭它。然后,在循环的下一次迭代中,您试图再次打开 SqlConnection
,由于连接已经打开,这会引发以下异常:
The connection was not closed. The connection's current state is open.
我对您的代码做了一些小改动,以演示处理 SqlConnection
(或实现 IDisposable
接口的任何其他对象)的正确方法。
Dim xmlFile As String
Dim connectionString As String
Dim ds As New DataSet
Dim reader As XmlReader
Dim sqlStatement As String
'Tag names inside xml document, will have to be inserted into table
Dim company As Integer
Dim name As String
Dim streetaddress As String
Dim city As String
Dim status As Char
connectionString = "this connection string works"
xmlFile = "MyXMLFile.xml"
reader = XmlReader.Create(xmlFile, New XmlReaderSettings())
ds.ReadXml(reader)
Dim doc As New XmlDocument()
doc.Load(xmlFile)
Dim nodelist As XmlNodeList = doc.SelectNodes(".//siteelement/site")
For Each node As XmlElement In nodelist
Dim i As Integer
For i = 0 To ds.Tables(0).Rows.Count - 1
company = Convert.ToInt32(ds.Tables(0).Rows(i).Item(0))
name = ds.Tables(0).Rows(i).Item(1)
streetaddress = ds.Tables(0).Rows(i).Item(2)
city = ds.Tables(0).Rows(i).Item(3)
status = ds.Tables(0).Rows(i).Item(4)
sqlStatement = "INSERT INTO [dbo].[SITE] ([COMPANY], [NAME], [STREETADDRESS], [CITY], [STATUS]) VALUES (@COMPANY, @NAME, @STREETADDRESS, @CITY, @STATUS)"
Using connection As New SqlConnection(connectionString)
Using command As New SqlCommand(sqlStatement, connection)
command.Parameters.AddWithValue("@COMPANY", company)
command.Parameters.AddWithValue("@NAME", name)
command.Parameters.AddWithValue("@STREETADDRESS", streetaddress)
command.Parameters.AddWithValue("@CITY", city)
command.Parameters.AddWithValue("@STATUS", status)
Try
connection.Open()
Dim rowsAffected As Integer = command.ExecuteNonQuery()
Console.WriteLine(rowsAffected & " entries were inserted into Site table")
'Release the resources
command.Dispose()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
'Execute the sql statement against the connection
command.ExecuteNonQuery()
End Using
End Using
Next
Next
您会注意到我将您的 SqlConnection
和 SqlCommand
包装在一个看起来很有趣的 Using
块中,而不是使用 Dim
关键字。 Using
块的目的是确保在到达 Using
块末尾时正确处理所有资源。
所以在我的代码示例中,SQLConnection
对象在循环的每次迭代中被完全销毁并重新创建,因此 connection.Open()
语句对每次迭代都有效。
显然在每次迭代时销毁并重新创建一个新的 SqlConnection
并不是最有效的方法,但我不想过多修改您的代码,因为您说您仍在学习。
或者,您可以简单地添加一行代码来关闭连接,例如 connection.Close()
,但我认为这展示了更好的编码实践。
当然,我用谷歌搜索了我的问题:"visual basic xml to sql how to insert many rows XmlReader"。我什至将 'many' 更改为 'multiple'.
到目前为止,我只能将 first 条目添加到我的数据库中。 我很高兴能够使用 XmlReader,因为我听说它非常高效。 我也很高兴能够使用参数,因为无论如何我都无法正确连接(是的,我喜欢优雅地编码 - 我不会在这里谈论我的衣服)。
我的VB.Net代码:
Imports System.Data.SqlClient
Imports System.Xml
Public Class Form1
Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
Dim xmlFile As String
Dim connectionString As String
Dim connection As SqlConnection
Dim command As SqlCommand
Dim ds As New DataSet
Dim reader As XmlReader
Dim sqlStatement As String
'Tag names inside xml document, will have to be inserted into table
Dim company As Integer
Dim name As String
Dim streetaddress As String
Dim city As String
Dim status As Char
connectionString = "this connection string works"
xmlFile = "MyXMLFile.xml"
connection = New SqlConnection(connectionString)
reader = XmlReader.Create(xmlFile, New XmlReaderSettings())
ds.ReadXml(reader)
Dim doc As New XmlDocument()
doc.Load(xmlFile)
Dim nodelist As XmlNodeList = doc.SelectNodes(".//siteelement/site")
For Each node As XmlElement In nodelist
Dim i As Integer
For i = 0 To ds.Tables(0).Rows.Count - 1
company = Convert.ToInt32(ds.Tables(0).Rows(i).Item(0))
name = ds.Tables(0).Rows(i).Item(1)
streetaddress = ds.Tables(0).Rows(i).Item(2)
city = ds.Tables(0).Rows(i).Item(3)
status = ds.Tables(0).Rows(i).Item(4)
sqlStatement = "INSERT INTO [dbo].[SITE] ([COMPANY], [NAME], [STREETADDRESS], [CITY], [STATUS])" &
"VALUES (@COMPANY, @NAME, @STREETADDRESS, @CITY, @STATUS)"
command = New SqlCommand(sqlStatement, connection)
command.Parameters.AddWithValue("@COMPANY", company)
command.Parameters.AddWithValue("@NAME", name)
command.Parameters.AddWithValue("@STREETADDRESS", streetaddress)
command.Parameters.AddWithValue("@CITY", city)
command.Parameters.AddWithValue("@STATUS", status)
Try
connection.Open()
Dim rowsAffected As Integer = command.ExecuteNonQuery()
MessageBox.Show(rowsAffected & " entries were inserted into Site table")
'Release the resources
command.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
'Execute the sql statement against the connection
command.ExecuteNonQuery()
Next
Next
connection.Close()
End Sub
End Class
我的 xml 文件是什么样的:
<?xml version="1.0" encoding="UTF-8"?>
<siteelement>
<site>
<company>1000</company>
<name>STORE #2336</name>
<streetAddress>123 London Calling</streetAddress>
<city>London</city>
<status>I</status>
</site>
<site>
<company>1001</company>
<name>STORE #2332</name>
<streetAddress>123 City of New Orleans</streetAddress>
<city>New Orleans</city>
<status>A</status>
</site>
<site>
<company>1002</company>
<name>STORE #2333</name>
<streetAddress>123 Bla bla bla</streetAddress>
<city>Somewhere</city>
<status>A</status>
</site>
</siteelement>
问题:如何让 reader 通读所有 xml 文档?我错过了什么?哪里不对?
任何帮助将不胜感激。请注意我是 Visual Basic 的新手(不到一周!),如果您认为我可以改进我的代码...
提前致谢。
在循环的第一次迭代中,您将打开 SqlConnection
,但永远不会关闭它。然后,在循环的下一次迭代中,您试图再次打开 SqlConnection
,由于连接已经打开,这会引发以下异常:
The connection was not closed. The connection's current state is open.
我对您的代码做了一些小改动,以演示处理 SqlConnection
(或实现 IDisposable
接口的任何其他对象)的正确方法。
Dim xmlFile As String
Dim connectionString As String
Dim ds As New DataSet
Dim reader As XmlReader
Dim sqlStatement As String
'Tag names inside xml document, will have to be inserted into table
Dim company As Integer
Dim name As String
Dim streetaddress As String
Dim city As String
Dim status As Char
connectionString = "this connection string works"
xmlFile = "MyXMLFile.xml"
reader = XmlReader.Create(xmlFile, New XmlReaderSettings())
ds.ReadXml(reader)
Dim doc As New XmlDocument()
doc.Load(xmlFile)
Dim nodelist As XmlNodeList = doc.SelectNodes(".//siteelement/site")
For Each node As XmlElement In nodelist
Dim i As Integer
For i = 0 To ds.Tables(0).Rows.Count - 1
company = Convert.ToInt32(ds.Tables(0).Rows(i).Item(0))
name = ds.Tables(0).Rows(i).Item(1)
streetaddress = ds.Tables(0).Rows(i).Item(2)
city = ds.Tables(0).Rows(i).Item(3)
status = ds.Tables(0).Rows(i).Item(4)
sqlStatement = "INSERT INTO [dbo].[SITE] ([COMPANY], [NAME], [STREETADDRESS], [CITY], [STATUS]) VALUES (@COMPANY, @NAME, @STREETADDRESS, @CITY, @STATUS)"
Using connection As New SqlConnection(connectionString)
Using command As New SqlCommand(sqlStatement, connection)
command.Parameters.AddWithValue("@COMPANY", company)
command.Parameters.AddWithValue("@NAME", name)
command.Parameters.AddWithValue("@STREETADDRESS", streetaddress)
command.Parameters.AddWithValue("@CITY", city)
command.Parameters.AddWithValue("@STATUS", status)
Try
connection.Open()
Dim rowsAffected As Integer = command.ExecuteNonQuery()
Console.WriteLine(rowsAffected & " entries were inserted into Site table")
'Release the resources
command.Dispose()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
'Execute the sql statement against the connection
command.ExecuteNonQuery()
End Using
End Using
Next
Next
您会注意到我将您的 SqlConnection
和 SqlCommand
包装在一个看起来很有趣的 Using
块中,而不是使用 Dim
关键字。 Using
块的目的是确保在到达 Using
块末尾时正确处理所有资源。
所以在我的代码示例中,SQLConnection
对象在循环的每次迭代中被完全销毁并重新创建,因此 connection.Open()
语句对每次迭代都有效。
显然在每次迭代时销毁并重新创建一个新的 SqlConnection
并不是最有效的方法,但我不想过多修改您的代码,因为您说您仍在学习。
或者,您可以简单地添加一行代码来关闭连接,例如 connection.Close()
,但我认为这展示了更好的编码实践。