kyrons Ответов: 3

Как игнорировать сохранение дубликатов записей перед вставкой в базу данных и продолжать сохранять другие неповторяющиеся записи с помощью VB.NET-что?


Я должен импортировать или копировать записи из одной базы данных в другую. Моя проблема заключается в том, что он постоянно вставляет записи, даже если они уже существуют. Я хочу контролировать вставку дубликатов записей. Я хочу, чтобы они игнорировались и вставлялись только те записи, которые не существуют в базе данных. Любое предложение или изменение в моем коде высоко ценится. Спасибо.

Что я уже пробовал:

Dim con1 As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= database1.accdb")
Dim con2 As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= database2.accdb")

con2.Open()
Dim CompQuery As String = "SELECT COUNT(*) FROM sampletable WHERE FirstName = @FirstName AND LastName = @LastName"
Dim compCommand As OleDbCommand = New OleDbCommand(CompQuery, con2)
compCommand.Parameters.AddWithValue("@FirstName", "FirstName")
compCommand.Parameters.AddWithValue("@LastName", "LastName")

If Convert.ToInt32(compCommand.ExecuteScalar()) > 0 Then
    'ignoring duplicate entries msgbox("Some records fail to save because it would create duplicate entries!")
    Exit Sub
Else

    'Create the data adapter with a SelectCommand using the first connection.
    Dim da As New OleDb.OleDbDataAdapter("SELECT Fullname, FirstName FROM table1 ", con1)
    'Add the InsertCommand with the second connection. 
    da.InsertCommand = New OleDb.OleDbCommand("INSERT INTO sampletable (Fullname, FirstName) VALUES (@FirstName, @LastName)", con2)
    'Add the insert parameters.                                                                                                 
    da.InsertCommand.Parameters.Add("@Fullname", OleDb.OleDbType.VarChar, 50, "FirstName")
    da.InsertCommand.Parameters.Add("@FirstName", OleDb.OleDbType.VarChar, 50, "LastName")
               'Keep the records in a state where they can be inserted into the destination table.
    da.AcceptChangesDuringFill = False
    Dim dt As New DataTable
    'Get the data from the source database.
    da.Fill(dt)
    'Save the data to the destination database.
    da.Update(dt)
    MsgBox("Data Added!")

    con1.Dispose()
    con2.Dispose()

End If

Richard MacCutchan

Используйте отладчик, чтобы узнать, какое значение возвращается предложением SELECT.

3 Ответов

Рейтинг:
2

Garth J Lancaster

Стандартным способом достижения этой цели было бы создание индекса в таблице базы данных с уникальными ограничениями - таким образом, вы не можете вводить дубликаты, не говоря уже о том, чтобы каким-то образом отфильтровывать их


Рейтинг:
2

CHill60

Чтобы придать немного плоти комментариям и предыдущему решению ..

Есть два способа сделать это, оба включают в себя убедиться, что вы не создаете дубликаты, а не иметь дело с ними впоследствии

1. Проверьте, чтобы увидеть, если элемент уже существует, прежде чем пытаться вставить его.
Это не подходит для массовых операций, но будет работать с вашим кодом. Это техника, которую вы, по-видимому, пытаетесь применить, см. ниже.

2. Как было предложено в решении 1 - Ограничьте базу данных так, чтобы данные не могли быть введены в первую очередь. Есть ссылки на то, как это сделать, в этом посте Codeproject - Остановить вставку дублированных записей в базу данных на языке Си#[^] - эта информация относится к SQL, поэтому игнорируйте "C#" в названии.

Я сказал выше, что вы пытались применить технику № 1 с помощью

Dim CompQuery As String = "SELECT COUNT(*) FROM sampletable WHERE FirstName = @FirstName AND LastName = @LastName"
Dim compCommand As OleDbCommand = New OleDbCommand(CompQuery, con2)
compCommand.Parameters.AddWithValue("@FirstName", "FirstName")
compCommand.Parameters.AddWithValue("@LastName", "LastName")
Я пока проигнорирую тот факт, что у вашего человека есть имя "Firstname" и фамилия "LastName" - вы явно ищете любого, кто имеет имя = "свойства FirstName" И LastName = "фамилия" в базе данных.

Но когда вы вставляете с помощью команды
da.InsertCommand = New OleDb.OleDbCommand("INSERT INTO sampletable (Fullname, FirstName) VALUES (@FirstName, @LastName)", con2)
В конечном итоге вы получите набор данных, который выглядит следующим образом
Fullname     FirstName    LastName
FirstName    NULL         LastName
Таким образом, либо ваш чек, чтобы узнать, существует ли он уже, должен измениться на
Dim CompQuery As String = "SELECT COUNT(*) FROM sampletable WHERE FullName = @FirstName AND LastName = @LastName"
или (что более вероятно) ваша вставка должна измениться на
da.InsertCommand = New OleDb.OleDbCommand("INSERT INTO sampletable (FirstName, LastName) VALUES (@FirstName, @LastName)", con2)
или еще что-нибудь.

tl;dr; - убедитесь, что ваши имена столбцов совпадают с тем, что вы, по вашему мнению, проверяете.

Редактировать после ОП комментарии

Вместо того чтобы использовать один и тот же dataadaptor как для чтения, так и для записи, попробуйте использовать 2 отдельных (передача данных между ними). Вы, кажется, пытаетесь вставить все из таблицы 1 в sampletable (нет оператора WHERE на вашем select), но затем пытаетесь также передать "FirstName" "LastName"). Разделение их может помочь вам увидеть, что происходит не так в отладчике.
В качестве альтернативы изменить
Dim da As New OleDb.OleDbDataAdapter("SELECT FirstName, LastName FROM table1 ", con1)
включать
Dim da As New OleDb.OleDbDataAdapter("SELECT FirstName, LastName FROM table1 ", con1)
включать
WHERE FirstName = @FirstName AND LastName = @LastName"
- не забудьте добавить эти параметры в команду select


kyrons

Извините, что в этой части кода ошибся. Это была просто типографская ошибка. Извини, что это сбивает тебя с толку.

"Но когда вы вставляете с командой

da.InsertCommand = New OleDb.OleDbCommand("вставить в sampletable (Fullname, FirstName) значения (@FirstName, @LastName)", con2)"

Вместо:

да.Команды Insertcommand = Новый Oledb Для.Объект oledbcommand("вставить в sampletable значений (Имя, Фамилия) (@Имя, @Фамилия)", con2)

kyrons

Это исправленные коды:

Код:
Дим видите con1 как новый oledb для.Метод Oledbconnection("Поставщик=Майкрософт.Туз.Oledb для.12.0;Источник данных= базы данных1.# то # ")
Дим con2 как новый oledb для.Метод Oledbconnection("Поставщик=Майкрософт.Туз.Oledb для.12.0;Источник данных= база данных 2.# то # ")

con2.Открыть()
Дим CompQuery как String = "выбрать количество(*) из sampletable где имя = @firstName и lastName = @фамилия"
Dim compCommand As OleDbCommand = New OleDbCommand(CompQuery, con2)
компкоманд.Параметры.AddWithValue("@FirstName", "FirstName")
компкоманд.Параметры.AddWithValue("@LastName", "LastName")

Если Новообращенный.ToInt32(compCommand.ExecuteScalar()) > 0 затем
'игнорирование дубликатов записей msgbox("некоторые записи не удается сохранить, потому что это создаст дубликаты
записи!")
Выход Из Субмарины
Еще

- Создайте адаптер данных с помощью команды SelectCommand, используя первое соединение.
Дим да как новый oledb для.Объект oledbdataadapter("выберите " имя", "фамилия" из таблицы table1 ", видите con1)
- Добавьте команду InsertCommand со вторым соединением.
папа.Команды Insertcommand = Новый Oledb Для.Объект oledbcommand("вставить в sampletable значений (Имя, Фамилия) (@Имя, @Фамилия)", con2)
- Добавьте параметры вставки.
папа.Команды insertcommand.Parameters.Add("@FirstName", OleDb.OleDbType.VarChar, 50, "FirstName")
папа.Команды insertcommand.Parameters.Add("@LastName", OleDb.OleDbType.VarChar, 50, "LastName")
- Храните записи в таком состоянии, чтобы их можно было вставить в таблицу назначения.
папа.AcceptChangesDuringFill = False
Дим ДТ в качестве нового объекта DataTable
- Возьмите данные из исходной базы данных.
да.Заполнить(ДТ)
- Сохраните данные в целевой базе данных.
да.Обновление(ДТ)
MsgBox("Добавлены Данные!")

вы видите con1.Располагать()
con2.Распоряжаться()

Конец, Если

CHill60

Я обновил свое решение с некоторыми предложениями

Рейтинг:
2

kgmmurugesh

Перед вставкой данных в новую таблицу проверьте, существует ли это имя уже или нет, используя запрос reaad. Надеюсь, это полезно..