Skip to content
Advertisement

Transfering Data with VBA(Excel) to SQL Server but avoiding duplicate column?

My main objective is to transfer some data from excel to SQL server while using vba but in the process I would like to detect and avoid transferring some duplicate month columns.

This is what i have so far:

Sub UploadExcelToSQL()

Dim adoCN As ADODB.Connection
Dim sConnString As String
Dim sSQL As String
Dim lRow As Long, lCol As Long

sConnString = "Provider=SQLOLEDB;Data Source=agrsql004instance01;Initial Catalog=DEHL;Integrated Security=SSPI"

Set adoCN = CreateObject("ADODB.Connection")

adoCN.Open sConnString


For lRow = 2 To 4

     sSQL = "INSERT INTO dbo.MonthlyValue (ID, Year, Month, Value) " & _
            " VALUES (" & _
            "'" & Sheet2.Cells(lRow, 1) & "', " & _
            "'" & Sheet2.Cells(lRow, 2) & "', " & _
            "'" & Sheet2.Cells(lRow, 3) & "', " & _
            "'" & Sheet2.Cells(lRow, 4) & "')"

    adoCN.Execute sSQL

Next lRow

adoCN.Close

Set adoCN = Nothing

End Sub

And will return something like:

ID  Year Month Value
123 2018   1   9987
123 2018   2   80988
123 2018   1   8990

What I would like is to have something like this:

ID  Year Month Value
123 2018   1   9987
123 2018   2   80988

In conclusion, I would like the code to detect the duplicate months of an equal year and avoid transferring it to the DB in SQL server so that one ID can only have one value per month of x year. My knowledge is pretty limited in this area still so any help would be greatly appreciated.

Advertisement

Answer

One solution would be to create a Unique constraint to the table on the cobination of the three columns ID, Year and Month:

Alter Table dbo.MonthlyValue 
    Add Constraint MonthlyValueUniqueContraint  UNIQUE (ID, Year, Month)

Note that you cannot create the constraint if you already have duplicates in your database – in that case you first have to cleanup your data.

This means that you can have multiple records with the same ID, the same year or the same month, you can even have multiple records for the same ID and same year (but different month) or same ID and month (but different year). Just the combination of ID, year and month would be unique.

When you try to insert a combination that already exists (eg like your 3rd row), the adoCN.Execute will throw an error – you have to catch this in your program so that it continues. Be carefull, the following code would ignore any error, if you want to have a robust solution, you should check the error code and only continue if it was a Unique-Contraint error (and not, for example an error because the connection dropped or one of the thousand other errors that may happen).

On Error Resume Next
adoCN.Execute sSQL
If Err.Number <> 0 Then Debug.Print Err.Number, Err.Description  
On Error GoTo 0

Of course, an alternative could always be to check if the record already exists in the database.
Disadvantage is that you need 2 round-trips to the database for every row, advantage is that you can implement an Update-statement if you want to keep the second rather than the first value. Or you could write a small stored procedure so that the logic is executed on database side – but I think that leads too far for now.

In any case, you should set the constraint – let the database watch that your data stays clean.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement