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


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
  • копії рядків, що повертаються тим самим первинним ключем.
  • невідповідність визначення колонки (наприклад, розмір полів char) між базою даних та набором даних

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

Або, щоб побачити точну помилку, ви можете вручну додати блок "Try / Catch" до генерованого коду, як, а потім порушити, коли виняток буде підвищено:

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

Потім у вікні команд виклик GetErrorsметоду виклику в таблиці отримання помилки.
Для C # команда була б ? dataTable.GetErrors()
для VB, команда така? dataTable.GetErrors

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

Це покаже вам всі дані, які мають помилку. Потім ви можете ознайомитись із 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
Так, це було дуже корисно - причиною моєї помилки було те, що довжина поля була довшою, ніж максимальна довжина стовпця в адаптері таблиці. Я зауважив одне, що для того, щоб потрапити на точку перелому у дизайнерському файлі, вам потрібно перейти до Інструменти> Параметри> Налагодження та переконайтесь, що "Увімкнути просто мій код" не встановлено прапорець. Після цього ви зможете переглядати код файлу дизайнера.
e-on

1
Дякую @PaulStock за те, що ти відповів, я вирішив свою проблему.
Удай

1
Це було надзвичайно корисно, я виявив невідповідність між довжиною стовпця даних - це було збільшено в базі даних, а не в наборі даних.
Роб

38

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

напр

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

Спосіб заливки для вас може дещо відрізнятися.


1
Це допомогло мені знайти дані, що спричинили мою проблему, яка була не "поганими даними", а скоріше поганою поведінкою майстра налаштування джерел даних. Мабуть, не отримуються переглянуті обмеження стовпців (і мені не вистачає доданої таблиці для завантаження), незважаючи на вихід та розмову з БД ... та кеш не ввімкнено.
fortboise

Дякую за цю відповідь. У мене виникла проблема з урахуванням регістру, і мені просто потрібно було її встановити належним чином у наборі даних.
День

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
Ласкаво просимо до SO, Боб. Я відредагував вашу відповідь (все ще переглядаюсь). Наприклад, ми вважаємо за краще не мати привітань та підписів у відповідях (це вважається "голосом", див. FAQ). Ваше ім’я та граватар завжди будуть відображатися нижче відповіді.
Крістофер Летте

5

Це працювало для мене, джерело: тут

У мене була ця помилка, і вона не була пов'язана з обмеженнями БД (принаймні в моєму випадку). У мене є .xsd файл із запитом GetRecord, який повертає групу записів. Один із стовпців цієї таблиці був "nvarchar (512)", і в середині проекту мені потрібно було змінити його на "nvarchar (MAX)".

Все працювало нормально, поки користувач не ввів більше 512 на це поле, і ми не почнемо отримувати відоме повідомлення про помилку "Не вдалося ввімкнути обмеження. Один або більше рядків містять значення, що порушують ненулеві, унікальні або зовнішні ключові обмеження".

Рішення: Перевірте всі властивості MaxLength стовпців у вашій DataTable.

Стовпець, який я змінив з "nvarchar (512)" на "nvarchar (MAX)", все ще мав значення 512 для властивості MaxLength, тому я змінив на "-1", і він працює !!.


Моя проблема, мабуть, була і MaxLength. Я використовую конструктор даних VWD 2010. Таблицю джерела змінив хтось інший. Я змінив SQL Query на select *, думаючи, що оновить усі стовпці, але, мабуть, він не оновив існуючі довжини. Тож я змінив запит, щоб вибрати одне поле, зберіг .xsd, відкрив .xsd у Блокноті ++, щоб перевірити, що всі, крім однієї з MaxLength деф, не було, а потім знову змінив запит на select *. ТОМУ оновив MaxLengths і змусив мене пройти через цю помилку.
Марк Беррі

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

4

Проблема полягає в конструкторі доступу до даних. У Visual Studio, коли ми перетягуємо вигляд із «Провідника сервера» до вікна «Дизайнер», він додає або Первинний ключ у стовпчик випадковим чином, або позначає щось НЕ НУЛЬ, хоча насправді встановлено на нуль. Хоча фактичне створення View на сервері SQL db не має жодного первинного ключа або визначено NOT NULL, VS-дизайнер додає цей ключ / обмеження.

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

Рішення: Клацніть правою кнопкою миші на значку клавіші та виберіть «Видалити ключ». Це повинно вирішити проблему. Ви також можете клацнути правою кнопкою миші на стовпці та вибрати "Властивості", щоб побачити список властивостей стовпця у дизайнері доступу до даних VS та змінити значення відповідно.


3

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

У моєму випадку у мене також є .xsd-об’єкт, який я розміщував там під час проектування (рівень доступу до даних). Коли ви перетягуєте об’єкти таблиці бази даних у візуальний елемент Набір даних, він зчитує кожне визначення таблиці з базової бази даних і копіює обмеження в об’єкт Набір даних точно так, як ви їх визначили під час створення таблиць у вашій базі даних (SQL Server 2008 R2 у моїй випадок). Це означає, що кожен стовпець таблиці, створений з обмеженням "не нульовий" або "зовнішній ключ", також повинен бути присутнім у результаті вашої операції SQL або збереженої процедури.

Після того, як я включив усі ключові стовпці та стовпці, визначені як "не нульові", у мої запити проблема повністю зникла.


3

Шахта почала працювати, коли я встановив AllowDBNullзначення True у полі дати в таблиці даних у файлі xsd.


2

Можливо, це здається, що один або декілька стовпців вибрано:

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

має AllowDBNull набір для Хибних в вашому Dataset Defintion.


Я ставлю дозволити 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

Дякую за весь внесок до цього часу. Я просто хочу додати, що, хоча хтось успішно нормалізував БД, оновив будь-які зміни схеми в їх застосуванні (наприклад, до набору даних) чи так, є ще одна причина: продукт CARTESIAN sql (при об'єднанні таблиць у запитах).

Наявність результату декартового запиту спричинить повторювані записи в первинній (або ключовій першої) таблиці двох або більше таблиць, що з'єднуються. Навіть якщо ви в SQL вказуєте пункт "Де", декартовий все-таки може виникати, якщо JOIN із вторинною таблицею, наприклад, містить нерівне з'єднання (корисно, коли отримувати дані з 2 або більше таблиць, що не пов'язані між собою):

ВІД tbFirst INNER ПРИЄДНАЙТЕСЬ tbSystem ON tbFirst.reference_str <> tbSystem.systemKey_str

Рішення для цього: таблиці повинні бути пов’язані між собою.

Дякую. чагбер


1

Я вирішив ту саму проблему, змінивши це з хибного на істинне. врешті-решт я зайшов у базу даних і змінив своє бітове поле, щоб дозволити null, а потім оновив свій xsd і оновив свій wsdl та reference.cs, і тепер все добре.

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

1

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

Перейдіть до MSSQL Studio Sever;

Запустіть запит про причину цієї помилки: у моєму випадку я бачу, що значення id було недійсним, оскільки я забуваю встановити приріст специфікації Identity на 1.

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

Таким чином, введено 1 для поля id, оскільки його є автоматичним збільшенням і модифікація не дозволяє NULLS у режимі перегляду

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

Це була помилка, яка спричинила помилку кидання мого прив'язки та адаптера Tabel у цьому коді:

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

0

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

Це безпосередньо дає помилку


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

0

Якщо ви використовуєте конструктор даних візуальних студій для отримання таблиці даних, і вона видає помилку "Не вдалося увімкнути обмеження". Я зіткнувся з тією ж проблемою, спробуйте переглянути дані самого дизайнера наборів даних і порівняти їх з таблицею всередині вашої бази даних.

Найкращий спосіб вирішити цю проблему - видалити адаптер таблиці та створити замість нього новий.


0

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


Якщо вам не потрібно, щоб [id] був основним ключем,

Видаліть його атрибут основного ключа:

у вашому DataSet> TableAdapter> клацніть правою кнопкою миші на стовпці [id]> виберіть Видалити ключ ...

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


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 ). Це означає, що кожен стовпець таблиці, створений з обмеженням "не нульовий" або "зовнішній ключ", також повинен бути присутнім у результаті вашої операції SQL або збереженої процедури.

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

Можливо, вам не потрібні всі стовпці таблиці, щоб вони були присутніми в результаті запиту / збереженої процедури, але, оскільки обмеження все ще застосовуються, помилка відображається, якщо якийсь обмежений стовпець не відображається в результаті.

Сподіваюсь, це допомагає комусь іншому.


-1

У моєму випадку ця помилка була спровокована розміром стовпчика рядків. Що було дивно, коли я виконував такий самий запит у різному інструменті, повторених значень чи нульових значень там не було.

Потім я виявив, що розмір стовпчика рядка дорівнював 50, тому коли я викликав метод заливки, значення було порубане, викинувши це виключення.
Я натискаю на стовпчик і встановлюю у властивостях розмір до 200, і помилка зникла.

Сподіваюся, що це допоможе


-1

Я вирішив цю проблему, зробивши такий "підбір", як це:

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

Коли це буде зроблено на mysql, всі властивості collunms (унікальні, ненульові ...) будуть очищені.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.