'Check if a record already exists in SQL Server table before inserting

I have an Excel table with 5 columns and 3 rows with data. Every time the data changes it is uploaded to DB. Below is my code to send data from the Excel table to the existing table in SQL Server. The challenge is, that the database accepts unique ID values. I would be grateful for your help on how to change the code that when ID in an Excel table already exists in the database? The code terminates with the message:

Duplicates are not allowed!

Sub IMPORT()

    Dim con As ADODB.Connection
    Dim cmd As ADODB.Command

    Set con = New ADODB.Connection
    Set cmd = New ADODB.Command

    Dim r As Range

    con.ConnectionString = sqlconstr
    con.Open "Provider=sqloledb;Data Source=DS;Initial Catalog=AUTO;Integrated Security=SSPI"

    cmd.ActiveConnection = con

    For Each r In Range("a2", Range("a2").End(xlDown))

        If r.Offset(0, 4).Value <> "" Then

            cmd.CommandText = cmd.CommandText & _
            GetInsertText( _
                r.Offset(0, 0).Value, _
                r.Offset(0, 1).Value, _
                r.Offset(0, 2).Value, _
                r.Offset(0, 3).Value, _
                r.Offset(0, 4).Value _
            )

        End If

    Next r

    Debug.Print cmd.CommandText

    cmd.Execute

    con.Close
    Set con = Nothing

    msgbox "Import successful"

End Sub
Function GetInsertText(ID As String, Date1 As Date, Date2 As Date, Reference As String, Price As Double)

    sql = _
        "insert into dbo.TP (" & _
        "ID, Date1, Date2, Reference, Price)" & _
        "values (" & _
        "'" & ID & "'," & _
        "'" & Format(Date1, "yyyy-mm-dd") & "'," & _
        "'" & Format(Date2, "yyyy-mm-dd") & "'," & _
        "'" & Reference & "'," & _
        Replace(Format(Price, "#0.00"), ",", ".") & ");"

    GetInsertText = sql

End Function 


Solution 1:[1]

I am not exactly certain that the syntax is correct, but you can try something like this:

Function ExistsAlready(ID As String, conn as Object) As Boolean

  Dim cmd As ADODB.Command

  Set cmd = New ADODB.Command

  cmd.CommandText = "select count(*) from dbo.TP where ID = '" & ID & "'"
  cmd.ActiveConnection = con
  Set rs = cmd.Execute

  ExistsAlready= rs.Fields(0).Value

End Function 

then you can use this to check if ID already exists in your table.

Solution 2:[2]

Consider MERGE with ADO parameterization which is supported with ADO Command and avoid concatenation of SQL in VBA strings.

SQL (save below in .sql file; notice use of ? qmarks)

MERGE dbo.TP AS target  
USING (VALUES (?, ?, ?, ?, ?)) 
      AS source(id, date1, date2, reference, price)
  
ON (target.id = source.id)  
WHEN MATCHED THEN
     UPDATE SET target.date1 = source.date1,
                target.date2 = source.date2,
                target.reference = source.reference,
                target.price = source.price  
WHEN NOT MATCHED THEN  
     INSERT (target.ID, 
             target.Date1,
             target.Date2,
             target.Reference,
             target.Price)  
     VALUES (source.ID,
             source.Date1,
             source.Date2, 
             source.Reference,
             source.Price); 

VBA (reads in SQL and binds parameters)

Noe: Below is untested code that may need adjustments. Adjust parameter values to align to corresponding ADO DataTypeNum.

Sub IMPORT()
    Dim con As ADODB.Connection, cmd As ADODB.Command
    Dim r As Range

    Set con = New ADODB.Connection
    Set cmd = New ADODB.Command

    con.ConnectionString = sqlconstr
    con.Open "Provider=sqloledb;Data Source=DS;Initial Catalog=AUTO;Integrated Security=SSPI"

    cmd.ActiveConnection = con

    ' READ SQL QUERY FROM FILE INTO STRING
    With CreateObject("Scripting.FileSystemObject")
        strSQL = .OpenTextFile("C:\path\to\my\SQL\Query.sql", 1).readall
    End With

    For Each r In Range("a2", Range("a2").End(xlDown))
        If r.Offset(0, 4).Value <> "" Then
            With cmd
                .CommandText = cmd.CommandText & strSQL
                
                ' BIND PARAMETERS WITH ? IN SQL (ALIGN VALUES TO ad TYPES)
                .Parameters.Append .CreateParameter("idparam", adVarChar, adParamInput, , r.Offset(0, 0).Value)
                .Parameters.Append .CreateParameter("dt1param", adDate, adParamInput, , r.Offset(0, 1).Value)
                .Parameters.Append .CreateParameter("dt2param", adDate, adParamInput, , r.Offset(0, 2).Value)
                .Parameters.Append .CreateParameter("refparam", adVarChar, adParamInput, , r.Offset(0, 3).Value)
                .Parameters.Append .CreateParameter("priceparam", adDecimal, adParamInput, , r.Offset(0, 4).Value)

                .Execute
            End With
        End If
    Next r

    cmd.close: con.Close
    Set cmd = Nothing: Set con = Nothing

    Msgbox "Import successful"
End Sub

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dejan Dozet
Solution 2