ssd_coolguy Ответов: 3

обновление таблицы, но почему она дает ошибку вставки ?


Я получаю ниже ошибку при обновлении адаптера данных.
"Нарушение ограничения первичного ключа 'PK__Compalint__62D5F22C'. Невозможно вставить дубликат ключа в объект 'Compalint'. Заявление было прекращено. "

я обновляю таблицу, но почему она дает ошибку вставки ?
Дайте мне знать, если я делаю что-то не так.. :(

я использовал приведенный ниже код:-

Dim Da As New SqlDataAdapter("select userid,loginid from compalint", conn)
  Dim cmdbld As New SqlCommandBuilder(Da)
     cmdbld.GetUpdateCommand()
         Da.Update(ds1, "table")


и мой ds1 содержит два поля userid,только loginid...

заранее спасибо...

Jim Jos

Что у вас есть в DS1? Пожалуйста, поместите код там, где вы получаете обновление строк DS1.. Если вы помещаете новые строки в DS1, он не будет обновляться, а только попытается вставить..

ssd_coolguy

спасибо за ответ...
набор данных ds1 содержит userid и loginid. и это происходит из xml-файла.
и я хочу обновить только поле loginid таблицы compalint.. потому что идентификатор является первичным ключом..
является ли мой код обновления dataadapter неправильным?

Jim Jos

Вам нужно обновить значение в dataset так, чтобы свойство 'RowState' было настроено на режим обновления.. тогда только оно будет обновляться.. вот почему я спрашиваю код, где вы обновляете набор данных. Вы говорите, что набор данных загружен из xml, но вы пытаетесь обновить таблицу.. DS1 должен быть взят из таблицы жалоб для обновления до работы.. в противном случае он будет вставлять только..

ssd_coolguy

Да, сэр, вы правы, нам нужно установить свойство 'RowState' в режиме обновления..
По вашему мнению, мы не можем обновить таблицу, если не возьмем набор данных только из этой таблицы..
Так есть ли способ решить эту проблему??

Извините за мой плохой английский :(

Jim Jos

Ладно, никаких проблем.. позвольте мне кратко изложить ваши требования.. 1. чтение данных из xml.. 2. Обновление таблицы жалоб с использованием данных, считанных из xml .. я прав?

ssd_coolguy

да, верно...

3 Ответов

Рейтинг:
24

Shahin Khorshidnia

Проверьте команду Update, я думаю, что она хочет изменить или вставить столбец PrimaryKey. Улучшите команду обновления.
Или
Вам нужно проверить ограничения таблицы в SQL Server. Удалите ненужные ограничения.
Или
После первого создания инструкции Transact-SQL приложение должно явно вызвать RefreshSchema, если оно каким-либо образом изменяет инструкцию. В противном случае команда GetUpdateCommand все равно будет использовать информацию из предыдущего оператора, что может быть неверно. Инструкции Transact-SQL сначала генерируются, когда приложение вызывает Update или GetUpdateCommand. (Более подробная информация в MSDN)

И еще, посмотри на это: Генерация команд с помощью CommandBuilders (ADO.NET)


ssd_coolguy

спасибо за ответ..
что вы имеете в виду под улучшением команды обновления? я не пишу никаких обновленных команд..
и моя таблица содержит только один первичный ключ "uesrid".
Не могли бы вы объяснить подробнее??

Shahin Khorshidnia

Пожалуйста. Пожалуйста, прочтите обновленное решение еще раз :)

ssd_coolguy

привет, Шахин .. я в замешательстве... :(

потому что.. когда я увидел commandtext из cmdbld.GetUpdateCommand().commandtext() и я получил ниже команду обновления..

Обновление [compalint] набор [ID пользователя] = @1 изн., [loginid] = @Р2, где (([идентификатор] = @P3) и ((@Р4 = 1 и [loginid] имеет значение null) или ([loginid] = @P5 в)))

команда обновления верна.. но почему это дает ошибку?? :( :(

Shahin Khorshidnia

Потому что вы не можете установить userId в команде update. UseID-это первичный ключ, и я уверен, что это идентификатор (означает автоматическое увеличение). как правило, вы не можете установить первичные ключи идентификации вручную.

ssd_coolguy

Эй, извините, но как я могу удалить его из списка обновлений... я пытался удалить из select, но он выдает ошибку, так как первичный ключ должен обновить оператор..:(

Shahin Khorshidnia

Я не знаю этого стола. Возможно, ему нужно увидеть запрос create t-sql таблицы. Но попробуйте использовать Select *. И... вы использовали его cmdbld.RefreshSchema() после Dim cmdbld As New SqlCommandBuilder(Da)? Он обновляет автоматически сгенерированную команду.
И кроме того, это настоящий стол или вид?!

ssd_coolguy

эй.. я использовал refreshschema(). и я проверил с помощью select *. но он запросил оставшиеся поля..:(

мой запрос create выглядит следующим образом :-CREATE TABLE [Compalint] (

[UserID] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,

[Name] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[Пароль] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[Email] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[LoginID] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[Type] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[ACTIVE_FLG] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[LAST_SIGN_IN] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[LAST_PWD_CHG] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

Первичный ключ кластеризованного ( [ID пользователя] ) на [основной] ) на [основной]иди

Shahin Khorshidnia

Я думал, что UserID-это Int или BigInt и Identity. Вот почему вы не можете обновить таблицу. Лучше было бы определить UserID как BigInt и установить его как Identity(1,1). Но теперь UserID не является нулевым, и вам нужно вставить в него значение при вставке и обновлении. Я думаю, что вы вставляете дубликат идентификатора пользователя или ничего не вставляете.

ssd_coolguy

Эй, Шахин ...спасибо за ответ..

ssd_coolguy

Эй, я думаю, что мы идем не в ту сторону..
вы можете просто посмотреть разговор между мной и Джимджосом.
я пытаюсь обновить набор данных с помощью dataadapter, но источником моих наборов данных является xml-файл...
ваша помощь была бы весьма ощутима...

Рейтинг:
17

Jim Jos

Вот решение (давайте использовать DataTable вместо DataSet)

1. пусть dt1 имеет xml-данные

Создание dt2 из БД

Dim Da As New SqlDataAdapter("select userid,loginid from compalint", conn)
        Dim cmdbld As New SqlCommandBuilder(Da)
        Dim dt2 As DataTable = New DataTable
        Da.Fill(dt2)


3. Теперь вам нужно пройти через каждую строку в dt1 и обновить dt2. Как только вы закончите обновление dt2, вызовите команду udpate..

Dim foundRows As DataRow()

For Each dRow As DataRow In dt1.Rows

    'search userid in Dt2
    foundRows = dt2.Select("userid = '" & dRow("UserId") & "'")
    'go thru each row in foundrows and update the value
    For Each dFoundRow As DataRow In foundRows
        dFoundRow("LoginId") = dRow("LoginId")
    Next

Next

dt2.AcceptChanges()

cmdbld.GetUpdateCommand()
Da.Update(dt2, "table")


ssd_coolguy

Да, босс, я думаю, что это сработает..
но смотри мой seanario..xml набор данных содержит только 2 строки, но другой набор данных содержит много строк..означает ли это, что мне нужно сделать связь данных между ними?

я очистил xmldataset и добавил в него datatable другого набора данных и попытался, но он дал ту же ошибку..:(

Jim Jos

Хорошо, подождите, я опубликую рабочее решение..

ssd_coolguy

хии...жду решения...:)

ssd_coolguy

Эй.. Большое спасибо!...
ваше решение версии 2 работает нормально.. :) :D
Спасибо..

Рейтинг:
0

Seth Owens

You need to update the value in dataset so that the 'RowState' property is set to UPDATE mode.. then only it will update.. that's y I am asking the code where you update the dataset. You are saying Dataset is loaded from xml but you are trying to update the table.. DS1 should be taken from Complaint table for update to work.. otherwise it will be inserting only..


Dave Kreskowiak

И я сомневаюсь, что они все еще ищут решение этой проблемы семь лет спустя.

OriginalGriff

См. s&ампер;на ...

Dave Kreskowiak

Да, я уже это сделал. Я опубликовал вышеизложенное, а затем нашел его в S&A, когда проверил через час.