Échec de l'activation des contraintes. Une ou plusieurs lignes contiennent des valeurs violant des contraintes non nulles, uniques ou de clé étrangère


168

Je crée une jointure externe et je l'exécute avec succès dans la informixbase de données mais j'obtiens l'exception suivante dans mon code:

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

Échec de l'activation des contraintes. Une ou plusieurs lignes contiennent des valeurs violant des contraintes de clé non nulle, unique ou étrangère.

Je connais le problème, mais je ne sais pas comment le résoudre.

La deuxième table sur laquelle je crée la jointure externe contient une clé primaire composite qui est nulle dans la requête de jointure externe précédente.

ÉDITER:

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

Le problème se produit avec la table cc1assiscrseval. La clé primaire est (batch_no, crsnum, lect_code).

Comment résoudre ce problème?


ÉDITER:

Selon les @PaulStockconseils: je fais ce qu'il a dit et j'obtiens:

? dt.GetErrors () [0] {System.Data.DataRow} HasErrors: true ItemArray: {object [10]} RowError: "La colonne 'eval' n'autorise pas DBNull.Value."

Je résous donc mon problème en remplaçant par e.eval, NVL (e.eval,'') evalet cela résout mon problème. Merci beaucoup.


Lorsque je supprime de ,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_coursela requête, tout va bien. quel est le problème s'il vous plaît.
Anyname Donotcare

Il existe également un bogue dans ADO.NET où un «index cluster non unique» créera un élément Data.UniqueConstraint erroné sur le DataTable.
Brain2000

Réponses:


352

Ce problème est généralement causé par l'un des éléments suivants

  • valeurs nulles renvoyées pour les colonnes non définies sur AllowDBNull
  • les lignes en double sont renvoyées avec la même clé primaire.
  • une non-concordance dans la définition de la colonne (par exemple la taille des champs de caractères) entre la base de données et l'ensemble de données

Essayez d'exécuter votre requête de manière native et examinez les résultats, si l'ensemble de résultats n'est pas trop volumineux. Si vous avez éliminé les valeurs nulles, je suppose que les colonnes de clé primaire sont dupliquées.

Ou, pour voir l'erreur exacte, vous pouvez ajouter manuellement un bloc Try / Catch au code généré comme ceci, puis rompre lorsque l'exception est déclenchée:

entrez la description de l'image ici

Ensuite, dans la fenêtre de commande, appelez la GetErrorsméthode sur la table pour obtenir l'erreur.
Pour C #, la commande serait ? dataTable.GetErrors()
Pour VB, la commande est? dataTable.GetErrors

entrez la description de l'image ici

Cela vous montrera toutes les datarows qui ont une erreur. Vous pouvez ensuite consulter le RowErrorpour chacun d'entre eux, ce qui devrait vous indiquer la colonne invalide ainsi que le problème. Donc, pour voir l'erreur du premier flux de données en erreur, la commande est:
? dataTable.GetErrors(0).RowError
ou en C # ce serait? dataTable.GetErrors()[0].RowError

entrez la description de l'image ici


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

4
Impressionnant. Cela n'a pas fonctionné, mais je pourrais ajouter une montre pour l'ensemble de données et taper .GetErrors après cela et développer les valeurs. C'est extrêmement utile. J'espère que je ne l'oublierai pas avant la prochaine fois que j'en
aurai

6
Oui, cela a été vraiment utile - la raison de mon erreur était que la longueur du champ était plus longue que la longueur maximale de la colonne dans l'adaptateur de table. Une chose que j'ai remarquée est que pour atteindre le point d'arrêt dans le fichier du concepteur, vous devez aller dans Outils> Options> Débogage, et assurez-vous que "Activer juste mon code" est décoché. Il vous permettra ensuite de parcourir le code du fichier du concepteur.
e-le

1
Merci @PaulStock pour votre réponse. J'ai résolu le même problème.
Uday

1
Cela a été extrêmement utile, j'ai trouvé une discordance entre la longueur des colonnes de données - elle a été augmentée dans la base de données et non dans l'ensemble de données.
Rob

38

Vous pouvez désactiver les contraintes sur l'ensemble de données. Cela vous permettra d'identifier les mauvaises données et de résoudre le problème.

par exemple

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

La méthode de remplissage peut être légèrement différente pour vous.


1
Cela m'a aidé à trouver les données à l'origine de mon problème, qui n'était pas de «mauvaises données» mais plutôt un mauvais comportement de l'assistant de configuration de source de données. Il ne reçoit apparemment pas de contraintes de colonne révisées (et il me manque une table supplémentaire pour démarrer), malgré le fait de sortir et de parler à la base de données ... et avec le cache non activé.
fortboise

Merci pour cette réponse. J'avais un problème sensible à la casse et j'avais juste besoin de le définir correctement dans l'ensemble de données.
Dan

10

Cela trouvera toutes les lignes de la table qui contiennent des erreurs, imprimera la clé primaire de la ligne et l'erreur qui s'est produite sur cette ligne ...

C'est en C #, mais le convertir en VB ne devrait pas être difficile.

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

Oups - désolé PKColumns est quelque chose que j'ai ajouté lorsque j'ai étendu DataTable qui me dit toutes les colonnes qui composent la clé primaire du DataTable. Si vous connaissez les colonnes de clé primaire dans votre table de données, vous pouvez les parcourir ici. Dans mon cas, puisque toutes mes tables de données connaissent leurs cols PK, je peux écrire le débogage pour ces erreurs automatiquement pour toutes les tables.

La sortie ressemble à ceci:

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

Si vous êtes confus au sujet de la section PKColumns ci-dessus, cela imprime les noms et les valeurs de colonne, et n'est pas nécessaire, mais ajoute des informations de dépannage utiles pour identifier les valeurs de colonne pouvant être à l'origine du problème. La suppression de cette section et la conservation du reste imprimera toujours l'erreur SQLite en cours de génération, qui notera la colonne qui présente le problème.


1
Un moyen génial de savoir exactement où cela s'est mal passé. Cela m'a totalement aidé à comprendre les problèmes dans une solution dont j'ai hérité où il y avait des incohérences avec les données. Bien que ce soit sur un DataSet et que je viens de parcourir chaque table, puis chaque ligne. +10 si je pouvais.
Andez

Cela a fonctionné pour moi. C'était un Column 'MyColumn' does not allow DBNull.Value, mais cela ne le montrerait pas autrement. Merci :)
Alex

7
  • Assurez-vous que les champs nommés dans la requête d'adaptateur de table correspondent à ceux de la requête que vous avez définie. Le DAL ne semble pas aimer les décalages. Cela arrivera généralement à vos sprocs et requêtes après avoir ajouté un nouveau champ à une table.

  • Si vous avez modifié la longueur d'un champ varchar dans la base de données et que le XML contenu dans le fichier XSS ne l'a pas récupéré, recherchez le nom du champ et la définition d'attribut dans le XML et modifiez-le manuellement.

  • Supprimez les clés primaires des listes de sélection dans les adaptateurs de table si elles ne sont pas liées aux données renvoyées.

  • Exécutez votre requête dans SQL Management Studio et assurez-vous qu'il n'y a pas d'enregistrements en double renvoyés. Les enregistrements en double peuvent générer des clés primaires en double, ce qui provoquera cette erreur.

  • Les unions SQL peuvent causer des problèmes. J'ai modifié un adaptateur de table en ajoutant un enregistrement «Veuillez sélectionner un employé» avant les autres. Pour les autres champs, j'ai fourni des données factices, y compris, par exemple, des chaînes de longueur un. La DAL a déduit le schéma de cet enregistrement initial. Les enregistrements suivants avec des chaînes de longueur 12 ont échoué.


1
Bienvenue à SO, Bob. J'ai modifié votre réponse (toujours en cours d'examen, cependant). Par exemple, nous préférons ne pas avoir de salutations et de signatures dans les réponses (c'est considéré comme "noice", veuillez consulter la FAQ). Votre nom et gravatar seront toujours affichés sous la réponse de toute façon.
Christoffer Lette

5

Cela a fonctionné pour moi, source: ici

J'ai eu cette erreur et elle n'était pas liée aux contraintes DB (du moins dans mon cas). J'ai un fichier .xsd avec une requête GetRecord qui renvoie un groupe d'enregistrements. L'une des colonnes de cette table était "nvarchar (512)" et au milieu du projet, j'avais besoin de la changer en "nvarchar (MAX)".

Tout fonctionnait bien jusqu'à ce que l'utilisateur en saisisse plus de 512 dans ce champ et que nous commencions à recevoir le fameux message d'erreur "Impossible d'activer les contraintes. Une ou plusieurs lignes contiennent des valeurs violant des contraintes non nulles, uniques ou de clé étrangère."

Solution: vérifiez toutes les propriétés MaxLength des colonnes de votre DataTable.

La colonne que j'ai changé de "nvarchar (512)" à "nvarchar (MAX)" avait toujours la valeur 512 sur la propriété MaxLength donc j'ai changé en "-1" et ça marche !!.


Mon problème doit également avoir été MaxLength. J'utilise le concepteur de jeux de données VWD 2010. La table source a été modifiée par quelqu'un d'autre. J'ai modifié la requête SQL en select *pensant que cela actualiserait toutes les colonnes, mais apparemment, cela n'a pas mis à jour les longueurs existantes. J'ai donc modifié la requête pour sélectionner un champ, enregistré le .xsd, ouvert le .xsd dans Notepad ++ pour vérifier que toutes les définitions de MaxLength sauf une avaient disparu, puis modifié à nouveau la requête select *. CELA a rafraîchi les MaxLengths et m'a permis de surmonter cette erreur.
Mark Berry

Merci beaucoup, je me suis gratté la tête sur celui-ci toute la journée car tout allait bien. J'ai également dû passer à nvarchar (MAX), mais le DataTable avait maintenu MaxLength à 10! Je te dois un verre!
Jon D

4

Le problème vient du concepteur d'accès aux données. Dans Visual Studio, lorsque nous extrayons une vue de «Explorateur de serveurs» vers la fenêtre Concepteur, il ajoute une clé primaire sur une colonne de manière aléatoire ou marque quelque chose sur NOT NULL bien qu'il soit en fait défini sur null. Bien que la création de vue réelle dans le serveur de base de données SQL n'ait pas de clé primaire définie ou NOT NULL défini, le concepteur VS ajoute cette clé / contrainte.

Vous pouvez le voir dans le concepteur - il est affiché avec une icône de clé à gauche du nom de la colonne.

Solution: faites un clic droit sur l'icône de la clé et sélectionnez «Supprimer la clé». Cela devrait résoudre le problème. Vous pouvez également cliquer avec le bouton droit de la souris sur une colonne et sélectionner «Propriétés» pour voir la liste des propriétés d'une colonne dans le concepteur d'accès aux données VS et modifier les valeurs de manière appropriée.


3

Cette erreur apparaissait également dans mon projet. J'ai essayé toutes les solutions proposées affichées ici, mais pas de chance car le problème n'avait rien à voir avec la taille des champs, la définition des champs clés de la table, les contraintes ou la variable de jeu de données EnforceConstraints.

Dans mon cas, j'ai également un objet .xsd que j'ai mis là pendant la conception du projet (la couche d'accès aux données). Lorsque vous faites glisser vos objets de table de base de données dans l'élément visuel Dataset, il lit chaque définition de table à partir de la base de données sous-jacente et copie les contraintes dans l'objet Dataset exactement comme vous les avez définies lorsque vous avez créé les tables dans votre base de données (SQL Server 2008 R2 dans mon Cas). Cela signifie que chaque colonne de table créée avec la contrainte «non nul» ou «clé étrangère» doit également être présente dans le résultat de votre instruction SQL ou procédure stockée.

Après avoir inclus toutes les colonnes clés et les colonnes définies comme «non nulles» dans mes requêtes, le problème a complètement disparu.


3

Le mien a commencé à fonctionner lorsque j'ai défini AllowDBNullsur True sur un champ de date sur une table de données dans le fichier xsd.


2

Cela ressemble peut-être à une ou plusieurs des colonnes sélectionnées avec:

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

a AllowDBNull défini sur False dans la définition de votre jeu de données.


J'ai mis allow null = true pour toutes les colonnes de ce tableau mais en vain.
Anyname Donotcare

2

Il n'est pas clair pourquoi l'exécution d'une instruction SELECT devrait impliquer des contraintes d'activation. Je ne connais pas C # ou les technologies associées, mais je connais la base de données Informix. Il se passe quelque chose d'étrange avec le système si votre code d'interrogation active (et probablement aussi désactive) des contraintes.

Vous devez également éviter la notation de jointure Informix OUTER désuète et non standard. À moins que vous n'utilisiez une version incroyablement ancienne d'Informix, vous devriez utiliser le style de jointures SQL-92.

Votre question semble mentionner deux jointures externes, mais vous n'en affichez qu'une dans l'exemple de requête. Cela aussi est un peu déroutant.

Les conditions de jonction entre « e» et le reste des tables sont:

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

C'est une combinaison inhabituelle. Puisque nous n'avons pas le sous-ensemble pertinent du schéma avec les contraintes d'intégrité référentielle pertinentes, il est difficile de savoir si c'est correct ou non, mais il est un peu inhabituel de joindre 3 tables comme ça.

Rien de tout cela n'est une réponse définitive à votre problème; cependant, il peut fournir des indications.


2

Merci pour toutes les contributions apportées jusqu'à présent. Je veux juste ajouter que bien que l'on ait pu normaliser avec succès la base de données, mettre à jour les modifications de schéma de leur application (par exemple à l'ensemble de données) ou ainsi, il y a aussi une autre cause: le produit sql CARTESIAN (lors de la jonction de tables dans des requêtes).

L'existence d'un résultat de requête cartésien entraînera des enregistrements en double dans la table primaire (ou clé en premier) de deux ou plusieurs tables jointes. Même si vous spécifiez une clause «Where» dans le SQL, un cartésien peut toujours se produire si JOIN avec table secondaire par exemple contient la jointure inégale (utile pour obtenir des données de 2 ou plusieurs tables UNrelated):

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

Solution pour cela: les tables doivent être liées.

Merci. Chagbert


1

J'ai résolu le même problème en changeant cela de faux en vrai. à la fin, je suis allé dans la base de données et j'ai changé mon champ de bits pour autoriser null, puis j'ai actualisé mon xsd, et actualisé mon wsdl et reference.cs et maintenant tout va bien.

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

1

Soloution courte et facile:

Accédez à MSSQL Studio Server;

Exécutez la requête de la cause de cette erreur: dans mon cas, je vois que la valeur de l'id était nulle car j'oublie de définir l' incrément de spécification d'identité de 1.

entrez la description de l'image ici

Donc entré 1 pour le champ id car il est autoincrémane et modifier ne pas autoriser NULLS dans la vue de conception

entrez la description de l'image ici

C'était l'erreur qui a provoqué l'erreur de lancement de ma source de liaison et de mon adaptateur tabel à ce code:

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

0

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

Cela donne directement l'erreur


2
Bonne suggestion, mais cela ne fonctionne que si c'est la première ligne de la table de données qui contient l'erreur, n'est-ce pas? Si 100 bonnes lignes sont renvoyées, puis 1 mauvaise ligne, il n'y aura pas de RowErrormarche Rows(0), n'est-ce pas?
PaulStock

0

Si vous utilisez le concepteur de jeux de données Visual Studio pour obtenir la table de données et qu'il renvoie une erreur «Échec d'activation des contraintes». J'ai rencontré le même problème, essayez de prévisualiser les données du concepteur de jeux de données lui-même et de les faire correspondre avec la table dans votre base de données.

La meilleure façon de résoudre ce problème est de supprimer l'adaptateur de table et d'en créer un nouveau à la place.


0

* Voie secondaire: *


Si vous n'avez pas besoin de [id] comme clé primaire,

Supprimez son attribut de clé primaire:

sur votre DataSet> TableAdapter> cliquez avec le bouton droit sur la colonne [id]> sélectionnez Supprimer la clé ...

Le problème sera résolu.


0

J'ai également eu ce problème et il a été résolu après la modification du * .xsd pour refléter la taille révisée de la colonne modifiée dans le serveur SQL sous-jacent.


0

Pour corriger cette erreur, j'ai enlevé l'adaptateur de table troublant du concepteur de jeu de données, et j'ai enregistré l'ensemble de données, puis j'ai fait glisser une nouvelle copie de l'adaptateur de table à partir de l'explorateur de serveur et cela l'a corrigé


0

J'ai résolu ce problème en ouvrant le fichier .xsd avec un lecteur XML et en supprimant une contrainte placée sur l'une de mes vues. Pour une raison quelconque, lorsque j'ai ajouté la vue aux données, cela a ajouté une contrainte de clé primaire à l'une des colonnes alors qu'il n'y en aurait pas eu.

L'autre façon consiste à ouvrir le fichier .xsd normalement, à regarder la table / vue à l'origine du problème et à supprimer toutes les clés (clic droit sur la colonne, sélectionnez delete key) qui ne devraient pas être là.


0

Je veux simplement ajouter une autre raison possible de l'exception à celles répertoriées ci-dessus (en particulier pour les personnes qui aiment définir le schéma de l'ensemble de données manuellement):

quand dans votre ensemble de données vous avez deux tables et qu'il y a une relation ( DataSet.Reletions.Add()) définie du champ de la première table ( chfield) au champ de la deuxième table ( pfield), il y a comme une contrainte implicite est ajoutée à ce champ pour être unique même si elle ne l'est pas spécifié comme tel explicitement dans votre définition ni comme unique ni comme clé primaire.

En conséquence, si vous avez des lignes avec des valeurs répétitives dans ce champ parent ( pfield), vous obtiendrez également cette exception.


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

J'ai reçu le même type d'erreur et dans mon cas, il l'a résolu en supprimant les champs de sélection et en les remplaçant par un *. Je ne sais pas pourquoi cela se passait. La requête n'avait aucune faute de frappe ou quoi que ce soit de fantaisie.

Pas la meilleure solution mais rien d'autre ne fonctionnait et j'étais épuisé.

Dans ma recherche d'une réponse claire, j'ai trouvé ceci sur ceci: https://www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont

Solution 8

Cette erreur apparaissait également dans mon projet, en utilisant Visual Studio 2010. J'ai essayé d'autres solutions publiées dans d'autres blogs, mais pas de chance car le problème n'avait rien à voir avec la taille des champs, la définition des champs clés de la table, les contraintes ou la EnforceConstraints variable jeu de données.

Dans mon cas, j'ai un objet .xsd que j'ai mis là pendant la conception du projet (dans la couche d'accès aux données). Lorsque vous faites glisser vos objets de table de base de données dans l'élément visuel du jeu de données, il lit chaque définition de table à partir de la base de données sous-jacente et copie les contraintes dans leDataset objet exactement comme vous les avez définies lorsque vous avez créé les tables dans votre base de données (SQL Server 2008 R2 dans mon cas ). Cela signifie que chaque colonne de table créée avec la contrainte «non nul» ou «clé étrangère» doit également être présente dans le résultat de votre instruction SQL ou procédure stockée.

Après avoir inclus toutes les colonnes contraintes (non nulles, clé primaire, clé étrangère, etc.) dans mes requêtes, le problème a complètement disparu.

Vous n'avez peut-être pas besoin que toutes les colonnes de la table soient présentes dans le résultat de la requête / procédure stockée, mais comme les contraintes sont toujours appliquées, l'erreur s'affiche si une colonne contrainte n'apparaît pas dans le résultat.

J'espère que ceci aide quelqu'un d'autre.


-1

Dans mon cas, cette erreur a été provoquée par une taille d'une colonne de chaîne. Ce qui était étrange, c'est lorsque j'ai exécuté exactement la même requête dans un outil différent, les valeurs répétées ni les valeurs nulles n'étaient pas là.

Ensuite, j'ai découvert que la taille d'une colonne de chaîne était de 50, alors quand j'ai appelé la méthode de remplissage, la valeur a été hachée, lançant cette exception.
Je clique sur la colonne et définit dans les propriétés la taille à 200 et l'erreur a disparu.

J'espère que cette aide


-1

J'ai résolu ce problème en faisant la "sous-sélection" comme ça:

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

Quand on le fait sur mysql, toutes les propriétés collunms (uniques, non nulles ...) seront effacées.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.