Заполнение данных SQLDataAdapter с помощью первичного ключа приводит к ошибке и выходит из подпрограммы - PullRequest
1 голос
/ 12 августа 2011

Хорошо, так что это займет некоторое объяснение.

Процесс, который я пытаюсь выполнить, - это получить данные из табличной функции в SQL, а затем заполнить набор данных возвращаемыми значениями. Затем мне нужно выполнить этот запрос еще два раза, чтобы запросить альтернативную таблицу номеров. Затем добавьте в ту же таблицу, что и предыдущие запросы. Это должно быть как можно быстрее, поэтому в настоящее время я использую adapter.fill для заполнения наборов данных, а затем dataset.merge, чтобы поместить их все в одну таблицу.

Проблема в том, что запрос может возвращать дубликаты, которые тратят время и пространство, поэтому я сделал столбец 3 (part_ID) первичным ключом для остановки дубликатов.

Когда он запускается с .merge, он завершается при первом экземпляре дублирования и не продолжается с заполнением.

Код ниже - это то, что я использовал, чтобы исправить это, мне просто было интересно, есть ли лучшее, более элегантное решение. </p> <pre> com = New SqlCommand(sqlPN, myConnect) adapter.SelectCommand = com adapter.Fill(temp, "Table(0)") Dim data As New DataSet data = temp temp.Tables(0).Columns(3).Unique = True firstSet = temp.Tables(0).Rows.Count temp.AcceptChanges() If temp.Tables(0).Rows.Count < maxRecords Then Dim sqlAlt As String = "select Top " & (maxRecords + 10 - temp.Tables(0).Rows.Count) & " * from getAltEnquiry('" & tbSearchFor.Text & "') ORDER BY spn_partnumber" adapter.SelectCommand.CommandText = sqlAlt adapter.FillLoadOption = LoadOption.OverwriteChanges adapter.Fill(temp, "Table(1)") For i = 0 To temp.Tables(1).Rows.Count - 1 Try temp.Tables(0).ImportRow(temp.Tables(1).Rows(i)) Catch e As Exception End Try Next End If If temp.Tables(0).Rows.Count < maxRecords Then Dim sqlSuPN As String = "select Top " & (maxRecords + 5 - temp.Tables(0).Rows.Count) & " * from getSuPNEnquiry('" & tbSearchFor.Text & "') ORDER BY spn_partnumber" adapter.SelectCommand.CommandText = sqlSuPN adapter.Fill(temp, "Table(2)") For i = 0 To temp.Tables(2).Rows.Count - 1 Try temp.Tables(0).ImportRow(temp.Tables(2).Rows(i)) Catch e As Exception End Try Next End If

Спасибо за любую помощь или совет ^ __ ^

1 Ответ

2 голосов
/ 14 августа 2011

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

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

Если это невозможно, вы можете вызвать адаптер. Заполните одну и ту же таблицу данных для каждого из ваших источников данных.Используйте перегрузку Fill, для заполнения которой требуется только DataTable, и согласно docs данные будут объединены вместе, если существует более одной записи с одним и тем же первичным ключом.То, как у вас вызывается метод Fill, это создание новой таблицы данных с именем, которое вы указываете при каждом вызове Fill.Вместо этого вы хотите заполнить только один DataTable.

"Вы можете использовать метод Fill несколько раз для одного и того же DataTable. Если первичный ключ существует, входящие строки объединяются с соответствующими строками, которые уже существуют. Если первичный ключ отсутствуетключ существует, входящие строки добавляются в таблицу данных. "

...