Передача данных с помощью VBA (Excel) на SQL Server, но избегая дублирования столбца? - PullRequest
0 голосов
/ 14 июня 2019

Моя основная задача - перенести некоторые данные из Excel на сервер SQL при использовании vba, но в процессе я хотел бы обнаружить и избежать переноса некоторых повторяющихся столбцов месяца.

Вот что у меня есть:

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=agrsql004\instance01;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

И вернет что-то вроде:

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

Я хотел бы иметь что-то вроде этого:

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

В заключение я хотел бы, чтобы код обнаруживал повторяющиеся месяцы одного и того же года и не передавал его в БД на сервере SQL, чтобы один идентификатор мог иметь только одно значение в месяц x года. Мои знания в этой области довольно ограничены, поэтому любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 14 июня 2019

Одним из решений было бы создание Уникального ограничения для таблицы на совокупность трех столбцов ID, Year и Month:

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

Обратите внимание , что вы не можете создать ограничение, если у вас уже есть дубликаты в вашей базе данных - в этом случае вам сначала нужно очистить ваши данные.

Это означает, что вы можете иметь несколько записей с одним и тем же идентификатором, одним и тем же годом или одним и тем же месяцем, вы даже можете иметь несколько записей для одного и того же идентификатора и того же года (но с разным месяцем) или одного и того же идентификатора и месяца (но с разным год). Просто сочетание идентификатора, года и месяца будет уникальным.

Когда вы пытаетесь вставить комбинацию, которая уже существует (например, ваша третья строка), adoCN.Execute выдаст ошибку - вы должны перехватить ее в своей программе, чтобы она продолжалась. Будьте осторожны, следующий код будет игнорировать любую ошибку, если вы хотите иметь надежное решение, вы должны проверить код ошибки и продолжить, только если это была ошибка Unique-Contraint (а не, например, ошибка из-за разрыва соединения или одной из тысячи других возможных ошибок).

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

Конечно, альтернативой всегда может быть проверка, существует ли запись в базе данных.
Недостатком является то, что для каждой строки требуется 2 обхода базы данных, преимущество заключается в том, что вы можете реализовать оператор Update, если хотите сохранить второе, а не первое значение. Или вы могли бы написать небольшую хранимую процедуру, чтобы логика выполнялась на стороне базы данных - но я думаю, что это слишком далеко.

В любом случае вы должны установить ограничение - пусть база данных следит за тем, чтобы ваши данные оставались чистыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...