web-dev-qa-db-fra.com

Insérer de nouveaux enregistrements uniquement dans la table SQL à l'aide de VBA

J'ai un classeur Excel avec le code ci-dessous -

Sub Button1_Click()
    Dim conn As New ADODB.Connection
    Dim iRowNo As Integer
    Dim sFirstName, sLastName As String

    With Sheets("Sheet1")

        'Open a connection to SQL Server
        conn.Open "Provider=SQLOLEDB;" & _
            "Data Source=server1;" & _
            "Initial Catalog=table1;" & _
            "User ID=user1; Password=pass1"

        'Skip the header row
        iRowNo = 2

        'Loop until empty cell in CustomerId
        Do Until .Cells(iRowNo, 1) = ""
            sFirstName = .Cells(iRowNo, 1)
            sLastName = .Cells(iRowNo, 2)

            'Generate and execute sql statement
            ' to import the Excel rows to SQL Server table
            conn.Execute "Insert into dbo.Customers (FirstName, LastName) " & _
                         "values ('" & sFirstName & "', '" & sLastName & "')"

            iRowNo = iRowNo + 1
        Loop

        MsgBox "Customers imported."

        conn.Close
        Set conn = Nothing

    End With

End Sub

Cela ouvre une connexion à ma base de données et entre les valeurs des colonnes indiquées.

La clé primaire est une clé incrémentielle de la base de données. Le problème est qu'il va copier TOUTES les valeurs.

J'aimerais ajouter de nouvelles lignes de données dans la feuille Excel et insérer uniquement les lignes qui n'existent pas déjà.

J'ai essayé différentes méthodes ('fusion', 'si existant', sinon existant ', etc.) mais je n'y arrive pas.

La solution doit être via VBA. La mise en place d'une liaison à l'aide de SSMS n'est pas une option.

Je comprends qu’il peut être possible d’utiliser des tables temporaires puis de déclencher une procédure qui effectue la fusion, mais j’aimerais examiner cette question en dernier recours. Je ne l'ai pas encore lu (en parcourant mon livre biblique MS SQL) mais j'espère que ce ne sera pas nécessaire.

--- Mise à jour de la réponse de @ Kannan ---

Nouvelle portion de VBA -

conn.Execute "IF EXISTS (SELECT 1 FROM dbo.Customers WHERE FirstName = '" &      sFirstName & "' and LastName = '" & sLastName & "') " & _
             "THEN UPDATE dbo.customers SET WHERE Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "' " & _
             "ELSE INSERT INTO dbo.Customers (FirstName, LastName) " & _
             "VALUES ('" & sFirstName & "', '" & sLastName & "')"

Cela renvoie l'erreur 'Syntaxe incorrecte près du mot clé' THEN '.

4
Jamsandwich

Votre requête SQL n'est pas tout à fait correcte - il n'y a pas de THEN dans un SQL IF.

En outre, vous n'avez rien à faire si cela existe, alors utilisez-le sinon.

"IF NOT EXISTS (SELECT 1 FROM dbo.Customers WHERE FirstName = '" & sFirstName & "' and LastName = '" & sLastName & "') " & _
         "INSERT INTO dbo.Customers (FirstName, LastName) " & _
         "VALUES ('" & sFirstName & "', '" & sLastName & "')"
7
BeanFrog

Cela devrait le faire pour vous.

Sub Button_Click()
'TRUSTED CONNECTION
    On Error GoTo errH

    Dim con As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim strPath As String
    Dim intImportRow As Integer
    Dim strFirstName, strLastName As String

    Dim server, username, password, table, database As String


    With Sheets("Sheet1")

            server = .TextBox1.Text
            table = .TextBox4.Text
            database = .TextBox5.Text


            If con.State <> 1 Then

                con.Open "Provider=SQLOLEDB;Data Source=" & server & ";Initial Catalog=" & database & ";Integrated Security=SSPI;"
                'con.Open

            End If
            'this is the TRUSTED connection string

            Set rs.ActiveConnection = con

            'delete all records first if checkbox checked
            If .CheckBox1 Then
                con.Execute "delete from tbl_demo"
            End If

            'set first row with records to import
            'you could also just loop thru a range if you want.
            intImportRow = 10

            Do Until .Cells(intImportRow, 1) = ""
                strFirstName = .Cells(intImportRow, 1)
                strLastName = .Cells(intImportRow, 2)

                'insert row into database
                con.Execute "insert into tbl_demo (firstname, lastname) values ('" & strFirstName & "', '" & strLastName & "')"

                intImportRow = intImportRow + 1
            Loop

            MsgBox "Done importing", vbInformation

            con.Close
            Set con = Nothing

    End With

Exit Sub

errH:
    MsgBox Err.Description
End Sub

Ajouter une référence à: Microsoft ActiveX Data Objects 2.8 Library

FYI, ma feuille ressemble à ceci.

 enter image description here

1
user7075507

Vous pouvez utiliser une requête SQL comme ceci:

IF Exists ( Select 1 from dbo.customers where Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "' THEN Update dbo.customers set --other columns where Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "'
ELSE Insert into dbo.Customers (FirstName, LastName) " & _
                     "values ('" & sFirstName & "', '" & sLastName & "')"

Pas sûr de la syntaxe pour Excel et C #, vous pouvez corriger cela de la même manière que cette requête

0
Kannan Kandasamy