177 votes

Échec de l'activation des contraintes. Une ou plusieurs lignes contiennent des valeurs violant les contraintes de non-nullité, d'unicité ou de clé étrangère.

Je fais une jointure externe et l'exécute avec succès dans le fichier informix 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 valeur non nulle, unique ou de clé étrangère.

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

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

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

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

Comment résoudre ce problème ?

EDIT :

Selon les conseils de @PaulStock : Je fais ce qu'il dit, et j'obtiens.. :

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

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

0 votes

Quand je retire ,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_course A partir de la requête, tout va bien. Quel est le problème ?

0 votes

Il existe également un bogue dans ADO.NET où un "index clusterisé non unique" créera un élément Data.UniqueConstraint erroné sur la DataTable.

375voto

PaulStock Points 4753

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

  • les valeurs nulles sont renvoyées pour les colonnes qui ne sont pas paramétrées pour AllowDBNull
  • des lignes en double sont retournées avec la même clé primaire.
  • un décalage dans la définition des colonnes (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 en mode natif et regardez les résultats, si le jeu de résultats n'est pas trop grand. Si vous avez éliminé les valeurs nulles, je pense que les colonnes de la 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 levée :

enter image description here

Puis, dans la fenêtre de commande, appelez GetErrors sur la table en obtenant l'erreur.
Pour C#, la commande serait ? dataTable.GetErrors()
Pour VB, la commande est ? dataTable.GetErrors

enter image description here

Cela vous montrera tous les flux de données qui ont une erreur. Vous pouvez alors regarder le RowError pour chacune d'entre elles, ce qui devrait vous indiquer la colonne qui est invalide ainsi que le problème. Donc, pour voir l'erreur de la première datarow en erreur la commande est :
? dataTable.GetErrors(0).RowError
ou en C#, ce serait ? dataTable.GetErrors()[0].RowError

enter image description here

4 votes

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

5 votes

Génial. Cela n'a pas fonctionné, mais j'ai pu ajouter une montre pour l'ensemble de données et taper .GetErrors après elle 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 besoin :)

6 votes

Oui, cela a été très utile - la raison de mon erreur était que la longueur du champ était supérieure à la longueur maximale de la colonne dans l'adaptateur de table. J'ai remarqué que pour atteindre le point d'arrêt dans le fichier du concepteur, vous devez aller dans Outils > Options > Débogage et vous assurer que l'option "Activer uniquement mon code" n'est pas cochée. Cela vous permettra alors d'avancer dans le code du fichier du concepteur.

41voto

HockeyJ Points 1408

Vous pouvez désactiver les contraintes sur l'ensemble de données. Cela vous permettra d'identifier les mauvaises données et vous aidera à 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 votes

Cela m'a aidé à trouver les données à l'origine de mon problème, qui n'était pas une "mauvaise donnée" mais plutôt un mauvais comportement de l'assistant de configuration de la source de données. Apparemment, il n'obtient pas les contraintes de colonne révisées (et il me manque une table ajoutée pour démarrer), malgré le fait qu'il aille parler à la base de données... et que le cache ne soit pas activé.

0 votes

Merci pour cette réponse. J'avais un problème de sensibilité à la casse et j'avais juste besoin de le définir de manière appropriée dans l'ensemble de données.

11voto

shindigo Points 447

Cette méthode permet de trouver toutes les lignes de la table qui présentent des erreurs, d'imprimer la clé primaire de la ligne et l'erreur qui s'est produite sur cette ligne...

Il est en C#, mais sa conversion 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 m'indique toutes les colonnes qui constituent la clé primaire de la DataTable. Si vous connaissez les colonnes de la clé primaire de votre table de données, vous pouvez les parcourir en boucle ici. Dans mon cas, puisque toutes mes tables de données connaissent leurs colonnes PK, je peux écrire un débogage pour ces erreurs automatiquement pour toutes les tables.

Le résultat ressemble à ceci :

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

1 votes

Une façon brillante de découvrir exactement où ça a mal tourné. Il m'a totalement aidé à comprendre les problèmes d'une solution dont j'ai hérité et qui présentait des incohérences dans les données. Bien que ce soit sur un DataSet et que j'ai juste itéré à travers chaque table, puis chaque ligne. +10 si je pouvais.

0 votes

Ça a marché pour moi. C'était un Column 'MyColumn' does not allow DBNull.Value mais il ne le montrerait pas d'une autre manière. Merci :)

7voto

Bob Sullentrup Points 51
  • Assurez-vous que les champs nommés dans la requête de l'adaptateur de table correspondent à ceux de la requête que vous avez définie. Le DAL ne semble pas apprécier les incompatibilités. C'est généralement le cas de vos sprocs et de vos requêtes après l'ajout d'un nouveau champ dans 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 détecté, trouvez le nom du champ et la définition de l'attribut dans le XML et modifiez-les manuellement.

  • Suppression des 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'aucun enregistrement en double n'est renvoyé. Les enregistrements en double peuvent générer des clés primaires en double, ce qui entraîne 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 fictives, par exemple des chaînes de caractères de longueur un. Le DAL a déduit le schéma de cet enregistrement initial. Les enregistrements suivants contenant des chaînes de caractères de longueur 12 ont échoué.

1 votes

Bienvenue chez SO, Bob. J'ai modifié votre réponse (toujours en cours de révision, cependant). Par exemple, nous préférons ne pas avoir de salutations et de signatures dans les réponses (c'est considéré comme "bruyant", voir la FAQ). De toute façon, votre nom et votre gravatar s'afficheront toujours en dessous de la réponse.

3voto

jgarcias Points 21

Cette erreur s'est également produite dans mon projet. J'ai essayé toutes les solutions proposées ici, mais sans succès 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 EnforceConstraints du jeu de données.

Dans mon cas, j'ai également un objet .xsd que j'ai placé là pendant la conception du projet (la couche d'accès aux données). Lorsque vous faites glisser les objets de table de votre base de données dans l'élément visuel Dataset, celui-ci 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 "not null" ou "foreign key" 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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X