【问题标题】:How to insert multiple rows from xml document to sql server using XmlReader如何使用 XmlReader 将多行从 xml 文档插入到 sql server
【发布时间】:2017-12-17 04:57:36
【问题描述】:

当然,我用谷歌搜索了我的问题:“visual basic xml to sql 如何插入多行 XmlReader”。我什至将“许多”改为“多个”。

到目前为止,我只能将 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>

问题:如何让我的读者阅读我所有的 xml 文档?我错过了什么?哪里不对?

任何帮助将不胜感激。请注意我是 Visual Basic 的新手(不到一周!),如果您认为我可以改进我的代码...

提前致谢。

【问题讨论】:

  • 看起来这会引发异常——在命令被释放后,您再次调用command.ExecuteNonQuery()(在内循环结束时)。我不知道是否还有其他问题,但请尝试删除该行并查看是否有帮助(您可能不应该在循环内打开连接)。您还应该查看 Using 语句以帮助清理资源。
  • 你是对的,这是抛出异常。固定。

标签: xml vb.net xmlreader


【解决方案1】:

在循环的第一次迭代中,您打开了 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

您会注意到我将您的SqlConnectionSqlCommand 包装在一个看起来很有趣的Using 块中,而不是使用Dim 关键字。 Using 块的目的是确保在到达Using 块的末尾时正确处理所有资源。

所以在我的代码示例中,SQLConnection 对象在循环的每次迭代中被完全销毁并重新创建,因此 connection.Open() 语句对每次迭代都有效。

显然,在每次迭代时销毁并重新创建一个新的 SqlConnection 并不是最有效的方法,但我不想过多地修改你的代码,因为你说你还在学习。

或者,您可以简单地添加一行代码来关闭连接,例如connection.Close(),但我觉得这表明了更好的编码实践。

【讨论】:

  • 对不起。出于某种奇怪的原因,我确实将 connection.Close() 放在了第二个 Next 语句之后(就在 End Sub 之前),但它没有显示在那里。我编辑它为时已晚,你已经这样做了。是的,请修改它,我学得越多,我就会变得越好。感谢您抽出宝贵时间,非常感谢您的态度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
  • 2018-08-02
相关资源
最近更新 更多