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

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

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

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

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

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

EDIT:

    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).

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


EDIT:

В соответствии с рекомендацией @PaulStock: Я делаю то, что он сказал, и я получаю:

? dt.GetErrors() [0] {System.Data.DataRow} HasErrors: true ItemArray: {object [10]} RowError: "Колонка" eval "не позволяет DBNull.Value."

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

Ответ 1

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

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

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

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

enter image description here

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

enter image description here

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

enter image description here

Ответ 2

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

например.

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

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

Ответ 3

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

Это в С#, но преобразование его в 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. Если вы знаете столбцы первичного ключа в своем datatable, вы можете просмотреть их здесь. В моем случае, поскольку все мои данные данных знают их PK cols, я могу автоматически отлаживать эти ошибки для всех таблиц.

Результат выглядит следующим образом:

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

Ответ 4

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

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

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

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

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

Ответ 5

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

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

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

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

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

Ответ 6

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

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

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

Ответ 7

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

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

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

Ответ 8

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

Ответ 9

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

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

имеет значение AllowDBNull, установленное в значение False в вашем определении Dataset.

Ответ 10

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

Вы также должны избегать старомодной нестандартной нотации Notix 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 

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

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

Ответ 11

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

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

ОТ tbFirst INNER JOIN                       tbSystem ON tbFirst.reference_str < > tbSystem.systemKey_str

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

Спасибо. chagbert

Ответ 12

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

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

Ответ 13

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

Это дает ошибку

Ответ 14

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

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

Ответ 15

* Вторичный путь: *


Если вам не нужен [id] как основной ключ,

Удалить свой первичный атрибут:

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

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

Ответ 16

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

Ответ 17

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

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

Ответ 18

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

Ответ 19

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

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

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

Ответ 20

            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();
                }
            }

Ответ 21

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

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

Надеемся на эту помощь

Ответ 22

Изначально я вызывал запрос, который возвращал один столбец и сохранял вывод запроса в DataTable.

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

Затем я выбрал конкретный столбец по его индексу из возвращаемого DataTable

Ответ 23

Я решил эту проблему, выполнив "subselect":

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

Когда это делается в mysql, все свойства collunms (unique, non-null...) будут очищены.