Не удалось включить ограничения. Одна или несколько строк содержат значения, нарушающие ненулевые, уникальные или внешние ключи


168

Я сделал внешнее соединение и успешно выполнил в informixбазе данных, но я получил следующее исключение в моем коде:

DataTable dt = TeachingLoadDAL.GetCoursesWithEvalState(i, bat);

Не удалось включить ограничения. Одна или несколько строк содержат значения, нарушающие ненулевые, уникальные или ограничения внешнего ключа.

Я знаю проблему, но я не знаю, как ее исправить.

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

РЕДАКТИРОВАТЬ:

    SELECT UNIQUE a.crs_e,  a.crs_e  || '/ ' || a.crst crs_name, b.period,
           b.crscls, c.crsday, c.from_lect, c.to_lect,
           c.to_lect - c.from_lect + 1 Subtraction, c.lect_kind, e.eval, e.batch_no,
           e.crsnum, e.lect_code, e.prof_course
    FROM rlm1course a, rfc14crsgrp b, ckj1table c, mnltablelectev d,
         OUTER(cc1assiscrseval e)  
    WHERE a.crsnum = b.crsnum 
    AND b.crsnum = c.crsnum 
    AND b.crscls = c.crscls 
    AND b.batch_no = c.batch_no 
    AND c.serial_key = d.serial_key  
    AND c.crsnum = e.crsnum  
    AND c.batch_no = e.batch_no  
    AND d.lect_code= e.lect_code 
    AND d.lect_code = .... 
    AND b.batch_no = ....

Проблема происходит со столом cc1assiscrseval. Первичный ключ (batch_no, crsnum, lect_code).

Как решить эту проблему?


РЕДАКТИРОВАТЬ:

Согласно @PaulStockсовету: я делаю то, что он сказал, и я получаю:

? dt.GetErrors () [0] {System.Data.DataRow} HasErrors: true ItemArray: {object [10]} RowError: «Столбец 'eval' не допускает DBNull.Value."

Поэтому я решаю свою проблему, заменяя e.evalна., NVL (e.eval,'') evalИ это решает мою проблему. Большое спасибо.


Когда я удаляю ,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_courseиз запроса все идет хорошо. в чем проблема пожалуйста.
Anyname Donotcare

В ADO.NET также есть ошибка, из-за которой «неуникальный кластерный индекс» создает ошибочный элемент Data.UniqueConstraint в DataTable.
Brain2000

Ответы:


352

Эта проблема обычно вызывается одним из следующих

  • нулевые значения, возвращаемые для столбцов, для которых не установлено значение AllowDBNull
  • повторяющиеся строки возвращаются с тем же первичным ключом.
  • несоответствие в определении столбца (например, размер полей символов) между базой данных и набором данных

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

Или, чтобы увидеть точную ошибку, вы можете вручную добавить блок Try / Catch в сгенерированный код следующим образом, а затем прервать его при возникновении исключения:

введите описание изображения здесь

Затем в командном окне вызовите GetErrorsметод таблицы, получив ошибку.
Для C # команда будет ? dataTable.GetErrors()
Для VB команда? dataTable.GetErrors

введите описание изображения здесь

Это покажет вам все datarows, которые имеют ошибку. Затем вы можете посмотреть на RowErrorкаждый из них, который должен указать вам недопустимый столбец вместе с проблемой. Итак, чтобы увидеть ошибку первого datarow в ошибке, команда:
? dataTable.GetErrors(0).RowError
или в C # это будет? dataTable.GetErrors()[0].RowError

введите описание изображения здесь


4
Большое спасибо . >? dt.GetErrors()[0] {System.Data.DataRow} HasErrors: true ItemArray: {object[10]} RowError: "Column 'eval' does not allow DBNull.Value."
Anyname Donotcare

4
Потрясающие. Это не сработало, но я мог бы добавить наблюдение за набором данных и набрать .GetErrors после него и развернуть значения. Это чрезвычайно полезно. Надеюсь, я не забуду это раньше, когда мне это понадобится в следующий раз :)
dwidel

6
Да, это было действительно полезно - причина моей ошибки была в том, что длина поля была больше, чем maxLength столбца в адаптере таблицы. Одна вещь, которую я заметил, заключалась в том, что для достижения точки останова в файле конструктора необходимо перейти в меню «Инструменты»> «Параметры»> «Отладка» и убедиться, что «Включить только мой код» не отмечено. Затем он позволит вам пройтись по коду файла конструктора.
7

1
Спасибо @PaulStock за ваш ответ. Я решил ту же проблему.
Uday

1
Это было чрезвычайно полезно, я обнаружил несоответствие между длиной столбца данных - оно было увеличено в базе данных, а не в наборе данных.
Роб

38

Вы можете отключить ограничения на наборе данных. Это позволит вам идентифицировать неверные данные и поможет решить проблему.

например

dataset.TableA.Clear();
dataset.EnforceConstraints = false;
dataAdapter1.daTableA.Fill(dataset, TableA");

Метод заполнения может немного отличаться для вас.


1
Это помогло мне найти данные, вызывающие мою проблему, которые были не «плохими данными», а скорее плохим поведением мастера настройки источника данных. Очевидно, он не получает пересмотренные ограничения на столбцы (и мне не хватает добавленной таблицы для загрузки), несмотря на то, что я выхожу и разговариваю с БД ... и кэш не включен.
Fortunboise

Спасибо за этот ответ. У меня была проблема с учетом регистра, и мне просто нужно было правильно установить ее в наборе данных.
Дан

10

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

Это в C #, но конвертировать его в VB не должно быть сложно.

 foreach (DataRow dr in dataTable)
 {
   if (dr.HasErrors)
     {
        Debug.Write("Row ");
        foreach (DataColumn dc in dataTable.PKColumns)
          Debug.Write(dc.ColumnName + ": '" + dr.ItemArray[dc.Ordinal] + "', ");
        Debug.WriteLine(" has error: " + dr.RowError);
     }
  }

К сожалению, извините, PKColumns - это то, что я добавил, когда расширил DataTable, который сообщает мне все столбцы, которые составляют первичный ключ DataTable. Если вы знаете столбцы первичного ключа в таблице данных, вы можете просмотреть их здесь. В моем случае, так как все мои таблицы данных знают свои столбцы PK, я могу написать отладку для этих ошибок автоматически для всех таблиц.

Вывод выглядит так:

Row FIRST_NAME: 'HOMER', LAST_NAME: 'SIMPSON', MIDDLE_NAME: 'J',  has error: Column 'HAIR_COLOR' does not allow DBNull.Value.

Если вы не уверены в приведенном выше разделе PKColumns - это печатает имена и значения столбцов и не является обязательным, но добавляет полезную информацию по устранению неполадок для определения того, какие значения столбцов могут вызывать проблему. При удалении этого раздела и сохранении остальных все равно будет напечатана сгенерированная ошибка SQLite, в которой будет указан столбец, в котором возникла проблема.


1
Отличный способ узнать, где именно это пошло не так. Полностью помог мне избежать проблем в решении, которое я унаследовал, где были несоответствия с данными. Хотя это было в DataSet, и я просто перебирал каждую таблицу, затем каждую строку. +10 если бы мог.
Андез

Это сработало для меня. Это было Column 'MyColumn' does not allow DBNull.Value, но это не показывало бы это любым другим способом. Спасибо :)
Алекс

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

  • Если вы изменили длину поля varchar в базе данных, а XML, содержащийся в файле XSS, не обнаружил его, найдите имя поля и определение атрибута в XML и измените его вручную.

  • Удалите первичные ключи из списков выбора в табличных адаптерах, если они не связаны с возвращаемыми данными.

  • Запустите запрос в SQL Management Studio и убедитесь, что не возвращаются повторяющиеся записи. Дублирующиеся записи могут генерировать дубликаты первичных ключей, что приведет к этой ошибке.

  • Союзы SQL могут означать проблемы. Я изменил один адаптер таблицы, добавив запись «Пожалуйста, выберите сотрудника», предшествующую другим. Для других полей я предоставил фиктивные данные, в том числе, например, строки длиной один. DAL выводит схему из этой начальной записи. Записи, следующие со строками длиной 12 не удалось.


1
Добро пожаловать, Боб. Я отредактировал ваш ответ (все еще в обзоре, хотя). Например, мы предпочитаем, чтобы в ответах не было приветствий и подписей (это считается «шумом», см. FAQ). Ваше имя и граватар всегда будут отображаться под ответом в любом случае.
Кристоффер Летт

5

Это сработало для меня, источник: здесь

У меня была эта ошибка, и она не была связана с ограничениями БД (по крайней мере, в моем случае). У меня есть файл .xsd с запросом GetRecord, который возвращает группу записей. Один из столбцов этой таблицы был «nvarchar (512)», и в середине проекта мне нужно было изменить его на «nvarchar (MAX)».

Все работало нормально, пока пользователь не ввел более 512 в это поле, и мы не начали получать известное сообщение об ошибке «Не удалось включить ограничения. Одна или несколько строк содержат значения, нарушающие ограничения ненулевого, уникального или внешнего ключа».

Решение. Проверьте все свойства MaxLength столбцов в DataTable.

Столбец, который я изменил с «nvarchar (512)» на «nvarchar (MAX)», все еще имел значение 512 для свойства MaxLength, поэтому я изменил на «-1», и это работает !!


Моя проблема, должно быть, была также MaxLength. Я использую конструктор наборов данных VWD 2010. Исходная таблица была изменена кем-то другим. Я изменил SQL-запрос select *, думая, что он обновит все столбцы, но, очевидно, он не обновил существующие длины. Поэтому я изменил запрос, выбрав одно поле, сохранил .xsd, открыл .xsd в Notepad ++, чтобы проверить, что все, кроме одного определения MaxLength, пропали, затем изменил запрос снова select *. Это обновило MaxLengths и избавило меня от этой ошибки.
Марк Берри

Большое спасибо, я целый день царапал свою голову, потому что все отчитывалось нормально. Мне также пришлось перейти на nvarchar (MAX), но DataTable сохранил MaxLength на 10! Я должен тебе выпить!
Джон Д

4

Проблема в конструкторе доступа к данным. В Visual Studio, когда мы извлекаем представление из «обозревателя сервера» в окно конструктора, он добавляет либо первичный ключ в столбце случайным образом, либо помечает что-то в NOT NULL, хотя на самом деле для него установлено значение NULL. Хотя фактическое создание View на сервере базы данных SQL не имеет ни первичного ключа, ни определенного NOT NULL, конструктор VS добавляет этот ключ / ограничение.

Вы можете увидеть это в дизайнере - это показано значком ключа слева от названия столбца.

Решение: Щелкните правой кнопкой мыши значок ключа и выберите «Удалить ключ». Это должно решить проблему. Вы также можете щелкнуть правой кнопкой мыши по столбцу и выбрать «Свойства», чтобы просмотреть список свойств столбца в конструкторе доступа к данным VS и соответствующим образом изменить значения.


3

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

В моем случае у меня также есть объект .xsd, который я помещаю туда во время разработки проекта (уровень доступа к данным). При перетаскивании объектов таблицы базы данных в визуальный элемент набора данных он считывает каждое определение таблицы из базовой базы данных и копирует ограничения в объект набора данных в точности так, как вы их определили при создании таблиц в вашей базе данных (SQL Server 2008 R2 в моем кейс). Это означает, что каждый столбец таблицы, созданный с ограничением «not null» или «external key», также должен присутствовать в результате вашего оператора SQL или хранимой процедуры.

После того, как я включил в свои запросы все ключевые столбцы и столбцы, определенные как «не ноль», проблема полностью исчезла.


3

Мой начал работать, когда я установил AllowDBNullзначение True в поле даты в таблице данных в файле xsd.


2

Похоже, что один или несколько столбцов выбираются с помощью:

   e.eval, e.batch_no, e.crsnum, e.lect_code, e.prof_course

имеет AllowDBNull набор для Ложных в вашем Dataset Defintion.


Я поставил allow null = true для всех столбцов в этой таблице, но тщетно.
Anyname Donotcare

2

Непонятно, почему выполнение оператора SELECT должно включать включающие ограничения. Я не знаю C # или связанных технологий, но я знаю базу данных Informix. В системе происходит что-то странное, если ваш код запроса включает (и, вероятно, также отключает) ограничения.

Вам также следует избегать старомодной нестандартной нотации соединения Informix OUTER. Если вы не используете невероятно старую версию Informix, вы должны использовать стиль соединений SQL-92.

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

Условия соединения между ' e' и остальными таблицами:

AND c.crsnum = e.crsnum  
AND c.batch_no = e.batch_no  
AND d.lect_code= e.lect_code 

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

Ничто из этого не является окончательным решением вашей проблемы; Тем не менее, это может дать некоторые рекомендации.


2

Спасибо за весь вклад, сделанный до сих пор. Я просто хочу добавить, что, хотя можно успешно нормализовать БД, обновить любые изменения схемы в своем приложении (например, в наборе данных) или около того, есть и другая причина: sql CARTESIAN product (при объединении таблиц в запросах).

Существование декартового результата запроса приведет к дублированию записей в первичной (или ключевой первой) таблице двух или более таблиц, которые будут объединены. Даже если вы зададите условие «Где» в SQL, декартово число может все же произойти, если, например, JOIN с вторичной таблицей содержит неравное соединение (полезно, когда нужно получить данные из 2 или более несвязанных таблиц):

ОТ tbFirst ВНУТРЕННЕЕ СОЕДИНЕНИЕ tbSystem ВКЛ tbFirst.reference_str <> tbSystem.systemKey_str

Решение для этого: таблицы должны быть связаны.

Спасибо. chagbert


1

Я решил ту же проблему, изменив ее с ложного на истинное. в конце концов я зашел в базу данных и изменил свое битовое поле, чтобы разрешить null, а затем обновил свой xsd и обновил мои wsdl и reference.cs, и теперь все в порядке.

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

1

Краткое и простое решение:

Зайдите в MSSQL Studio Север;

Запустите запрос причины этой ошибки: в моем случае я вижу, что значение id было нулевым, потому что я забыл установить приращение спецификации Identity на 1.

введите описание изображения здесь

Таким образом, введено 1 для поля id, так как оно является autoincremane и изменить не разрешать NULLS в представлении дизайна

введите описание изображения здесь

Это была ошибка, которая вызвала мою ошибку подключения bindingsource и tabel адаптера в этом коде:

   this.exchangeCheckoutReportTableAdapter.Fill(this.sbmsDataSet.ExchangeCheckouReportTable);

0

DirectCast (dt.Rows (0), DataRow) .RowError

Это напрямую дает ошибку


2
Хорошее предложение, но это работает, только если в первой строке таблицы данных есть ошибка, не так ли? Если будет возвращено 100 хороших строк, а затем 1 плохая, не будет ли RowErrorвключен Rows(0), не так ли?
PaulStock

0

Если вы используете дизайнер наборов данных Visual Studio для получения таблицы данных, и он выдает ошибку «Не удалось включить ограничения». Я столкнулся с той же проблемой, попробуйте предварительно просмотреть данные самого дизайнера наборов данных и сопоставить их с таблицей в вашей базе данных.

Лучший способ решить эту проблему - удалить адаптер таблицы и создать новый.


0

* Вторичный способ: *


Если вам не нужно, чтобы [id] был первичным ключом,

Удалите атрибут первичного ключа:

в вашем DataSet> TableAdapter> щелкните правой кнопкой мыши по столбцу [id]> выберите Delete key ...

Проблема будет исправлена.


0

У меня также была эта проблема, и она была решена после изменения * .xsd, чтобы отразить измененный размер столбца, измененного в базовом сервере SQL.


0

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


0

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

Другой способ - открыть файл .xsd обычным способом, посмотреть на таблицу / представление, вызывающее проблему, и удалить все ключи (столбец правой кнопкой мыши, выберите delete key), которых там быть не должно.


0

Просто хочу добавить еще одну возможную причину исключения из перечисленных выше (особенно для людей, которым нравится определять схему набора данных вручную):

когда в вашем наборе данных у вас есть две таблицы и существует отношение ( DataSet.Reletions.Add()), определенное из поля первой таблицы ( chfield) к полю второй таблицы ( pfield), существует неявное ограничение, добавляемое в это поле, чтобы быть уникальным, даже если оно не указано в качестве такового в вашем определении ни как уникальный, ни как первичный ключ.

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


0
            using (var tbl = new DataTable())
            using (var rdr = cmd.ExecuteReader())
            {
                tbl.BeginLoadData();

                try
                {
                    tbl.Load(rdr);
                }
                catch (ConstraintException ex)
                {
                    rdr.Close();
                    tbl.Clear();

                    // clear constraints, source of exceptions
                    // note: column schema already loaded!
                    tbl.Constraints.Clear();
                    tbl.Load(cmd.ExecuteReader());
                }
                finally
                {
                    tbl.EndLoadData();
                }
            }

0

Я получил тот же тип ошибки, и в моем случае она была решена путем удаления полей выбора и замены их на *. Понятия не имею, почему это происходит. В запросе не было опечаток или чего-то необычного.

Не лучшее решение, но больше ничего не помогло, и я истощался.

В поисках четкого ответа я нашел это по следующему адресу : https://www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont

Решение 8

Эта ошибка также проявлялась в моем проекте с использованием Visual Studio 2010. Я попробовал другие решения, опубликованные в других блогах, но не повезло, потому что проблема не имела никакого отношения к размеру полей, определению полей таблицы ключей, ограничениям или EnforceConstraintsпеременной набора данных.

В моем случае у меня есть объект .xsd, который я помещаю туда во время разработки проекта (на уровне доступа к данным). Когда вы перетаскиваете объекты таблицы базы данных в визуальный элемент набора данных, она считывает каждое определение таблицы из базовой базы данных и копирует ограничения в Datasetобъект точно так, как вы их определили при создании таблиц в вашей базе данных (в моем случае SQL Server 2008 R2). ). Это означает, что каждый столбец таблицы, созданный с ограничением «not null» или «external key», также должен присутствовать в результате вашего оператора SQL или хранимой процедуры.

После того, как я включил в свои запросы все ограниченные столбцы (не ноль, первичный ключ, внешний ключ и т. Д.), Проблема полностью исчезла.

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

Надеюсь, это поможет кому-то еще.


-1

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

Затем я обнаружил, что размер строкового столбца равен 50, поэтому, когда я вызвал метод fill, значение было обрезано, и это исключение было вызвано.
Я нажимаю на столбец и устанавливаю в свойствах размер 200, и ошибка исчезла.

Надеюсь это поможет


-1

Я решил эту проблему, выполнив «подобрать» так:

string newQuery = "select * from (" + query + ") as temp";

Когда это делается в MySQL, все свойства столкновения (уникальные, ненулевые ...) будут очищены.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.