Error al habilitar restricciones. Una o más filas contienen valores que violan restricciones no nulas, únicas o de clave externa


168

Realizo una unión externa y la ejecuté con éxito en la informixbase de datos, pero obtengo la siguiente excepción en mi código:

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

Error al habilitar restricciones. Una o más filas contienen valores que violan restricciones no nulas, únicas o de clave externa.

Conozco el problema, pero no sé cómo solucionarlo.

La segunda tabla en la que hago la unión externa contiene una clave primaria compuesta que es nula en la consulta de unión externa anterior.

EDITAR:

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

El problema ocurre con la mesa cc1assiscrseval. La clave principal es (batch_no, crsnum, lect_code).

¿Cómo arreglar este problema?


EDITAR:

De acuerdo con el @PaulStockconsejo: hago lo que dijo, y obtengo:

? dt.GetErrors () [0] {System.Data.DataRow} HasErrors: true ItemArray: {object [10]} RowError: "La columna 'eval' no permite DBNull.Value".

Así que resuelvo mi problema reemplazando e.evala., NVL (e.eval,'') evalY esto resuelve mi problema. Muchas gracias.


Cuando elimino de ,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_coursela consulta, todo sale bien. cual es el problema por favor
Anyname Donotcare

También hay un error en ADO.NET donde un "índice agrupado no único" creará un elemento Data.UniqueConstraint erróneo en la DataTable.
Brain2000

Respuestas:


352

Este problema generalmente es causado por uno de los siguientes

  • valores nulos que se devuelven para columnas no establecidas en AllowDBNull
  • filas duplicadas que se devuelven con la misma clave primaria.
  • Un desajuste en la definición de columna (por ejemplo, el tamaño de los campos de caracteres) entre la base de datos y el conjunto de datos

Intente ejecutar su consulta de forma nativa y observe los resultados, si el conjunto de resultados no es demasiado grande. Si ha eliminado los valores nulos, supongo que las columnas de la clave principal se están duplicando.

O, para ver el error exacto, puede agregar manualmente un bloque Try / Catch al código generado de esta manera y luego romperlo cuando se genera la excepción:

ingrese la descripción de la imagen aquí

Luego, dentro de la ventana de comandos, llame al GetErrorsmétodo en la tabla obteniendo el error.
Para C #, el comando sería ? dataTable.GetErrors()
Para VB, el comando es? dataTable.GetErrors

ingrese la descripción de la imagen aquí

Esto le mostrará todos los datarows que tienen un error. Luego puede ver RowErrorcada uno de estos, lo que debería indicarle la columna que no es válida junto con el problema. Entonces, para ver el error del primer datarow por error, el comando es:
? dataTable.GetErrors(0).RowError
o en C # sería? dataTable.GetErrors()[0].RowError

ingrese la descripción de la imagen aquí


44
Muchas gracias . >? dt.GetErrors()[0] {System.Data.DataRow} HasErrors: true ItemArray: {object[10]} RowError: "Column 'eval' does not allow DBNull.Value."
Anyname Donotcare

44
Increíble. Eso no funcionó, pero podría agregar un reloj para el conjunto de datos y escribir .GetErrors después de él y expandir los valores. Eso es extremadamente útil. Espero no olvidarlo antes de la próxima vez que lo necesite :)
dwidel

66
Sí, esto fue realmente útil: la razón de mi error fue que la longitud del campo era más larga que la longitud máxima de la columna en el adaptador de la tabla. Una cosa que noté fue que para alcanzar el punto de interrupción en el archivo del diseñador, debe ir a Herramientas> Opciones> Depuración y asegurarse de que "Habilitar solo mi código" esté desmarcado. Luego le permitirá recorrer el código del archivo del diseñador.
e-

1
Gracias @PaulStock por tu respuesta. Tengo mi mismo problema resuelto.
Uday

1
Esto fue extremadamente útil, encontré una falta de coincidencia entre la longitud de la columna de datos: aumentó en la base de datos y no en el conjunto de datos.
Rob

38

Puede deshabilitar las restricciones en el conjunto de datos. Le permitirá identificar datos incorrectos y ayudará a resolver el problema.

p.ej

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

El método de relleno puede ser ligeramente diferente para usted.


1
Esto me ayudó a encontrar los datos que causaron mi problema, que no eran "datos incorrectos", sino un mal comportamiento del Asistente de configuración de origen de datos. Aparentemente no está recibiendo restricciones de columna revisadas (y me falta una tabla adicional para arrancar), a pesar de salir y hablar con el DB ... y con el caché no habilitado.
fortboise

Gracias por esta respuesta Tenía un problema de mayúsculas y minúsculas y solo necesitaba configurarlo adecuadamente en el conjunto de datos.
Dan

10

Esto encontrará todas las filas en la tabla que tienen errores, imprimirá la clave principal de la fila y el error que ocurrió en esa fila ...

Esto está en C #, pero convertirlo a VB no debería ser difícil.

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

Vaya, lo siento PKColumns es algo que agregué cuando extendí DataTable que me dice todas las columnas que conforman la clave principal de DataTable. Si conoce las columnas de Clave primaria en su tabla de datos, puede recorrerlas aquí. En mi caso, dado que todas mis tablas de datos conocen sus valores de PK, puedo escribir la depuración de estos errores automáticamente para todas las tablas.

El resultado se ve así:

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

Si está confundido acerca de la sección PKColumns anterior, imprime los nombres y valores de las columnas, y no es necesario, pero agrega información útil para la resolución de problemas para identificar qué valores de las columnas pueden estar causando el problema. Al eliminar esta sección y conservar el resto, todavía se imprimirá el error SQLite que se genera, lo que notará la columna que tiene el problema.


1
Brillante forma de averiguar exactamente dónde salió mal. Totalmente me ayudó a resolver problemas insondables en una solución que heredé donde había inconsistencias con los datos. Aunque estaba en un DataSet y solo recorrí cada tabla, luego cada fila. +10 si pudiera.
Andez

Esto funcionó para mí. Era un Column 'MyColumn' does not allow DBNull.Value, pero no lo demostraría de otra manera. Gracias :)
Alex

7
  • Asegúrese de que los campos nombrados en la consulta del adaptador de tabla coincidan con los de la consulta que ha definido. Al DAL no parece gustarle los desajustes. Esto normalmente ocurrirá con sus consultas y consultas después de agregar un nuevo campo a una tabla.

  • Si ha cambiado la longitud de un campo varchar en la base de datos y el XML contenido en el archivo XSS no lo ha recogido, busque el nombre del campo y la definición de atributo en el XML y cámbielo manualmente.

  • Elimine las claves principales de las listas seleccionadas en los adaptadores de tabla si no están relacionadas con los datos que se devuelven.

  • Ejecute su consulta en SQL Management Studio y asegúrese de que no se devuelven registros duplicados. Los registros duplicados pueden generar claves primarias duplicadas que causarán este error.

  • Las uniones SQL pueden deletrear problemas. Modifiqué un adaptador de mesa agregando un registro de "seleccione un empleado" antes de los demás. Para los otros campos proporcioné datos ficticios que incluyen, por ejemplo, cadenas de longitud uno. El DAL dedujo el esquema de ese registro inicial. Los registros que siguen con cadenas de longitud 12 fallaron.


1
Bienvenido a SO, Bob. He editado su respuesta (aunque todavía en revisión). Por ejemplo, preferimos no tener saludos y firmas en las respuestas (se considera "ruido", consulte las preguntas frecuentes). Su nombre y gravatar siempre se mostrarán debajo de la respuesta de todos modos.
Christoffer Lette

5

Esto funcionó para mí, fuente: aquí

Tuve este error y no estaba relacionado con las restricciones de DB (al menos en mi caso). Tengo un archivo .xsd con una consulta GetRecord que devuelve un grupo de registros. Una de las columnas de esa tabla era "nvarchar (512)" y en el medio del proyecto necesitaba cambiarlo a "nvarchar (MAX)".

Todo funcionó bien hasta que el usuario ingresó más de 512 en ese campo y comenzamos a recibir el famoso mensaje de error "Error al habilitar restricciones. Una o más filas contienen valores que violan restricciones no nulas, únicas o de clave externa".

Solución: compruebe toda la propiedad MaxLength de las columnas en su DataTable.

La columna que cambié de "nvarchar (512)" a "nvarchar (MAX)" todavía tenía el valor 512 en la propiedad MaxLength, así que cambié a "-1" y funciona.


Mi problema también debe haber sido MaxLength. Yo uso el diseñador de conjuntos de datos VWD 2010. La tabla fuente fue cambiada por otra persona. Modifiqué la consulta SQL a select *, pensando que actualizaría todas las columnas, pero aparentemente no actualizó las longitudes existentes. Así que modifiqué la consulta para seleccionar un campo, guardé el .xsd, abrí el .xsd en Notepad ++ para verificar que todas las definiciones de MaxLength, excepto una, desaparecieron, y luego modifiqué la consulta nuevamente select *. ESO actualizó los MaxLengths y me ayudó a superar este error.
Mark Berry

Muchas gracias, me he estado rascando la cabeza sobre esto todo el día ya que todo me estaba yendo bien. También tuve que cambiar a nvarchar (MAX), ¡pero DataTable había mantenido MaxLength en 10! ¡Te debo un trago!
Jon D

4

El problema es con el diseñador de acceso a datos. En Visual Studio, cuando extraemos una Vista del "Explorador del servidor" a la ventana del Diseñador, agrega una Clave principal en una columna al azar o marca algo en un NOT NULL aunque en realidad está configurado como nulo. Aunque la creación de la vista real en el servidor SQL db no tiene una clave principal definida o NO está definido NULL, el diseñador de VS está agregando esta clave / restricción.

Puede ver esto en el diseñador: se muestra con un icono de llave a la izquierda del nombre de la columna.

Solución: haga clic con el botón derecho en el icono de la tecla y seleccione 'Eliminar clave'. Esto deberia resolver el problema. También puede hacer clic con el botón derecho en una columna y seleccionar "Propiedades" para ver la lista de propiedades de una columna en el diseñador de acceso a datos VS y cambiar los valores adecuadamente.


3

Este error también se mostró en mi proyecto. Intenté todas las soluciones propuestas publicadas aquí, pero no tuve suerte porque el problema no tenía nada que ver con el tamaño de los campos, la definición de los campos clave de la tabla, las restricciones o la variable del conjunto de datos EnforceConstraints.

En mi caso, también tengo un objeto .xsd que puse allí durante el tiempo de diseño del proyecto (la capa de acceso a datos). A medida que arrastra los objetos de la tabla de la base de datos al elemento visual del conjunto de datos, lee cada definición de tabla de la base de datos subyacente y copia las restricciones en el objeto del conjunto de datos exactamente como las definió cuando creó las tablas en su base de datos (SQL Server 2008 R2 en mi caso). Esto significa que cada columna de tabla creada con la restricción de "no nulo" o "clave externa" también debe estar presente en el resultado de su instrucción SQL o procedimiento almacenado.

Después de incluir todas las columnas clave y las columnas definidas como "no nulas" en mis consultas, el problema desapareció por completo.


3

El mío comenzó a funcionar cuando configuré AllowDBNullTrue en un campo de fecha en una tabla de datos en el archivo xsd.


2

Parece que posiblemente una o más de las columnas se seleccionan con:

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

tiene AllowDBNull establecido en False en la definición de su conjunto de datos.


Puse allow null = true para todas las columnas de esta tabla pero en vano.
Anyname Donotcare

2

No está claro por qué ejecutar una instrucción SELECT debería implicar restricciones habilitadoras. No conozco C # o tecnologías relacionadas, pero sí conozco la base de datos Informix. Algo extraño sucede con el sistema si su código de consulta está habilitando (y presumiblemente también deshabilitando) restricciones.

También debe evitar la notación de unión de Informix OUTER antigua y no estándar. A menos que esté utilizando una versión imposiblemente antigua de Informix, debería estar utilizando el estilo de combinaciones SQL-92.

Su pregunta parece mencionar dos combinaciones externas, pero solo muestra una en la consulta de ejemplo. Eso también es un poco desconcertante.

Las condiciones de unión entre ' e' y el resto de las tablas son:

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

Esta es una combinación inusual. Dado que no tenemos el subconjunto relevante del esquema con las restricciones de integridad referencial relevantes, es difícil saber si esto es correcto o no, pero es un poco inusual unir entre 3 tablas como esa.

Nada de esto es una respuesta definitiva a su problema; Sin embargo, puede proporcionar alguna orientación.


2

Gracias por todos los aportes realizados hasta ahora. Solo quiero agregar que, si bien uno puede haber normalizado con éxito la base de datos, actualizado cualquier cambio de esquema en su aplicación (por ejemplo, en el conjunto de datos), hay otra causa: el producto sql CARTESIAN (al unir tablas en consultas).

La existencia de un resultado de consulta cartesiana causará registros duplicados en la tabla primaria (o clave primero) de dos o más tablas que se unen. Incluso si especifica una cláusula "Where" en el SQL, puede aparecer un cartesiano si JOIN con una tabla secundaria, por ejemplo, contiene la unión desigual (útil cuando se obtienen datos de 2 o más tablas no relacionadas):

DESDE tbFirst INNER JOIN tbSystem ON tbFirst.reference_str <> tbSystem.systemKey_str

Solución para esto: las tablas deben estar relacionadas.

Gracias. chagbert


1

Resolví el mismo problema cambiando esto de falso a verdadero. al final entré en la base de datos y cambié mi campo de bits para permitir nulo, y luego actualicé mi xsd, y actualicé mi wsdl y reference.cs y ahora todo está bien.

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

1

Solución breve y fácil:

Vaya a MSSQL Studio Sever;

Ejecute la consulta de la causa de este error: en mi caso, veo que el valor de identificación era nulo porque olvido establecer el incremento de especificación de identidad en 1.

ingrese la descripción de la imagen aquí

Entonces ingresó 1 para el campo id ya que es autoincremanente y modificar no permite NULLS en la vista de diseño

ingrese la descripción de la imagen aquí

Ese fue el error que causó el error de lanzamiento de mi adaptador de enlace y fuente tabel en este código:

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

0

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

Esto da directamente el error


2
Buena sugerencia, pero eso solo funciona si es la primera fila de la tabla de datos la que tiene el error, ¿no? Si se devuelven 100 filas correctas y luego 1 fila incorrecta, no habrá un RowErrorencendido Rows(0), ¿ verdad ?
PaulStock

0

Si está utilizando el diseñador de conjuntos de datos de Visual Studio para obtener la tabla de datos, y está arrojando un error 'Error al habilitar restricciones'. Me he enfrentado al mismo problema, intente obtener una vista previa de los datos del diseñador del conjunto de datos y cotejarlo con la tabla dentro de su base de datos.

La mejor manera de resolver este problema es eliminar el adaptador de mesa y crear uno nuevo.


0

* Forma secundaria: *


Si no necesita que [id] sea como clave principal,

Elimine su atributo de clave principal:

en su DataSet> TableAdapter> haga clic derecho en la columna [id]> seleccione Eliminar clave ...

El problema se solucionará.


0

También tuve este problema y se resolvió después de modificar el * .xsd para reflejar el tamaño revisado de la columna modificada en el servidor SQL subyacente.


0

Para solucionar este error, quité el problemático adaptador de mesa del diseñador del conjunto de datos, guardé el conjunto de datos y luego arrastré una copia nueva del adaptador de la tabla desde el explorador del servidor y eso lo solucionó


0

Resolví este problema abriendo el archivo .xsd con un lector XML y eliminando una restricción colocada en una de mis vistas. Por alguna razón, cuando agregué la vista a los datos, agregó una restricción de clave principal a una de las columnas cuando no debería haber una.

La otra forma es abrir el archivo .xsd normalmente, mirar la tabla / vista que causa el problema y eliminar cualquier tecla (columna de clic derecho, seleccionar delete key) que no debería estar allí.


0

Solo quiero agregar otro posible motivo de la excepción a los enumerados anteriormente (especialmente para las personas a las que les gusta definir el esquema del conjunto de datos manualmente):

cuando en su conjunto de datos tiene dos tablas y hay una relación ( DataSet.Reletions.Add()) definida desde el campo de la primera tabla ( chfield) hasta el campo de la segunda tabla ( pfield), existe la posibilidad de que se agregue una restricción implícita a ese campo para que sea única aunque no lo sea especificado como tal explícitamente en su definición ni como clave única ni principal.

Como consecuencia, si tiene filas con valores repetitivos en ese campo primario ( pfield), también obtendrá esta excepción.


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

Recibí el mismo tipo de error y en mi caso lo resolvió eliminando los campos seleccionados y reemplazándolos con un *. No tengo idea de por qué estaba sucediendo. La consulta no tenía errores tipográficos ni nada elegante.

No es la mejor solución, pero nada más funcionó y me estaba agotando.

En mi búsqueda de una respuesta clara, encontré esto en esto: https://www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont

Solución 8

Este error también se mostró en mi proyecto, usando Visual Studio 2010. Probé otras soluciones publicadas en otros blogs, pero no tuve suerte porque el problema no tenía nada que ver con el tamaño de los campos, la definición de los campos clave de la tabla, las restricciones o la EnforceConstraintsvariable del conjunto de datos.

En mi caso, tengo un objeto .xsd que puse allí durante el tiempo de diseño del proyecto (en la capa de acceso a datos). A medida que arrastra los objetos de la tabla de la base de datos al elemento visual del conjunto de datos, lee cada definición de tabla de la base de datos subyacente y copia las restricciones en el Datasetobjeto exactamente como las definió cuando creó las tablas en su base de datos (SQL Server 2008 R2 en mi caso ) Esto significa que cada columna de tabla creada con la restricción de "no nulo" o "clave externa" también debe estar presente en el resultado de su instrucción SQL o procedimiento almacenado.

Después de incluir todas las columnas restringidas (no nulas, clave principal, clave externa, etc.) en mis consultas, el problema desapareció por completo.

Quizás no necesite que todas las columnas de la tabla estén presentes en el resultado de la consulta / procedimiento almacenado, pero debido a que las restricciones aún se aplican, el error se muestra si alguna columna restringida no aparece en el resultado.

Espero que esto ayude a alguien más.


-1

En mi caso, este error fue provocado por el tamaño de una columna de cadena. Lo extraño fue cuando ejecuté exactamente la misma consulta en una herramienta diferente, los valores repetidos ni los valores nulos no estaban allí.

Luego descubrí que el tamaño de una columna de cadena era 50, por lo que cuando llamé al método de relleno, el valor se cortó, arrojando esta excepción.
Hago clic en la columna y establezco en las propiedades el tamaño de 200 y el error desapareció.

Espero que esto ayude


-1

Resolví este problema haciendo la "subselección" como esta:

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

Cuando lo haga en mysql, se borrarán todas las propiedades de collunms (únicas, no nulas ...).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.