使用vb.net从excel文件更新SQL表

时间:2016-08-25 12:09:02

标签: sql sql-server vb.net excel

我编写了一个小程序,它在输入中获取.xlsx文件(此文件定期更新),并将数据提取到sql表。 我想通过比较excel文件的内容和sql表的内容来定期更新这个sql表,并将所有新行(如果存在)插入其中。 我搜索了许多解决方案但没有成功。 我该怎么办?

我的实际代码如下:

Dim ExcelConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & SourceFile & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes""")
        ExcelConnection.Open()
        Dim RequeteExcelMat As String = "SELECT * FROM [feuil 1$]"
        Dim objCmdSelect As OleDbCommand = New OleDbCommand(RequeteExcelMat, ExcelConnection)
        Dim objDR As OleDbDataReader

        Dim ConnexionBDDMat As New SqlConnection("SERVER=(local);DATABASE=MatStat;Trusted_Connection=True")

        Try
            ConnexionBDDMat.Open()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

        Using bulkCopy As SqlBulkCopy = New SqlBulkCopy(ConnexionBDDMat)
            bulkCopy.DestinationTableName = "dbo.Material"

            'If SourceFile Content different from "Material" Sql Table Content Then
            '   Update "Material" Table by inserting the new rows from SourceFile 
            'Else
            ' MsgBox("Table is already updated")
            'End If

            Try
                objDR = objCmdSelect.ExecuteReader
                bulkCopy.WriteToServer(objDR)
                objDR.Close()
                ConnexionBDDMat.Close()

            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
        End Using

3 个答案:

答案 0 :(得分:1)

使用名为MaterialStaging的相同模式创建另一个表。批量插入此表而不是常规表。

然后,运行使用MERGE命令的存储过程来查找生产表和登台表之间的差异,并更新或插入差异。

答案 1 :(得分:1)

我使用它来处理一个小表来更新/插入从Excel到SQL Server的数据

Sub merge()
    Dim CurConn As ADODB.Connection
    Dim rst As ADODB.Recordset
    Dim SomeName As Worksheet
    Dim Lastrow, Sql, n, i

    Set SomeName = Sheets("SomeName")

    Lastrow = SomeName.Range("B" & Rows.Count).End(xlUp).Row

    For i = 2 To Lastrow

        If i < Lastrow Then
            Sql = Sql + "(" + CStr(SomeName.Range("A" & i).Value) + ", '" + SomeName.Range("B" & i).Value + "', '" + SomeName.Range("C" & i).Value + "', '" + SomeName.Range("D" & i).Value + "', '" + SomeName.Range("E" & i).Value + "', '" + SomeName.Range("F" & i).Value + "'),"
        Else
            Sql = Sql + "(" + CStr(SomeName.Range("A" & i).Value) + ", '" + SomeName.Range("B" & i).Value + "', '" + SomeName.Range("C" & i).Value + "', '" + SomeName.Range("D" & i).Value + "', '" + SomeName.Range("E" & i).Value + "', '" + SomeName.Range("F" & i).Value + "')"
        End If

    Next i

    Set CurConn = New ADODB.Connection
    CurConn.Open "Provider=SQLNCLI11;Server=SERVER\INSTANCE;Database=DATABASENAME;Trusted_Connection=yes;"
    CurConn.CommandTimeout = 180
    CurConn.CursorLocation = adUseClient

    Sql = "MERGE [dbo].[SomeName] as target " _
    & "USING (" _
    & "    SELECT [Userid]" _
    & "          ,[Login]" _
    & "          ,[name]" _
    & "          ,[org]" _
    & "          ,[pos]" _
    & "          ,[mail]" _
    & "    FROM (VALUES" _
    & Sql _
    & "    ) as t([Userid],[Login],[name],[org],[pos],[mail])" _
    & ") as source " _
    & "ON target.[Userid] =source.[Userid] AND target.[Login] =source.[Login] " _
    & "WHEN MATCHED THEN " _
    & "    UPDATE SET  target.[name] =source.[name], " _
    & "                target.[org] =source.[org], " _
    & "                target.[pos] =source.[pos], " _
    & "                target.[mail] = Source.[mail] " _
    & "WHEN NOT MATCHED THEN " _
    & "    INSERT ([Userid],[Login],[name],[org],[pos],[mail]) " _
    & "    VALUES (source.[Userid],source.[Login],source.[name],source.[org],source.[pos],source.[mail]); "

    MsgBox ("Success!")
    CurConn.Execute (Sql)

    CurConn.Close
    Set rst = Nothing
    Set CurConn = Nothing
End Sub

将Excel表格转换为VALUES (1,2,3,4,5,6),(7,8,9,10,11,12)..etc很奇怪,但它运行正常。你可以采用这个解决方案和f.e.插入一些临时表,然后像上面所示合并它。

答案 2 :(得分:0)

不要使用VB。在SQL Server中执行此操作,并使用MERGE命令,如Russ所建议的那样。

https://www.simple-talk.com/sql/learn-sql-server/the-merge-statement-in-sql-server-2008/