Je fais une jointure externe et exécuté avec succès dans la base de données informix
mais j'obtiens l'exception suivante dans mon code:
DataTable dt = TeachingLoadDAL.GetCoursesWithEvalState(i, bat);
Impossible d'activer les contraintes. Une ou plusieurs lignes contiennent des valeurs ne respectant pas les contraintes non nulles, uniques 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 réalise la jointure externe contient une clé primaire composite qui est nulle dans la requête de jointure externe précédente.
MODIFIER:
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?
MODIFIER:
Selon @PaulStock
conseil: je fais ce qu'il a dit et je reçois:
? dt.GetErrors () [0] {System.Data.DataRow} HasErrors: true ItemArray: {object [10]} RowError: "La colonne 'eval' n'autorise pas DBNull.Value."
Donc, je résous mon problème en remplaçant e.eval
par, NVL (e.eval,'') eval
. Et cela résout mon problème. Merci beaucoup.
Ce problème est généralement causé par l’un des problèmes suivants:
Essayez d'exécuter votre requête en mode natif 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 la clé primaire sont en cours de duplication.
Ou, pour voir l'erreur exacte, vous pouvez ajouter manuellement un bloc Try/Catch au code généré, comme ceci, puis une interruption lorsque l'exception est déclenchée:
Ensuite, dans la fenêtre de commande, appelez la méthode GetErrors
sur la table en obtenant l'erreur.
Pour C #, la commande serait ? dataTable.GetErrors()
Pour VB, la commande est ? dataTable.GetErrors
Cela vous montrera tous les datarows qui ont une erreur. Vous pouvez alors regarder la RowError
pour chacun d’eux, ce qui devrait vous indiquer la colonne invalide avec le problème. Donc, pour voir l'erreur du premier datarow en erreur, la commande est la suivante:? dataTable.GetErrors(0).RowError
ou en C #, ce serait ? dataTable.GetErrors()[0].RowError
Vous pouvez désactiver les contraintes sur le jeu 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.
Cela trouvera toutes les lignes de la table qui contiennent des erreurs, affichera la clé primaire de la ligne et l'erreur survenue sur cette ligne ...
Ceci 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é lors de l'extension de DataTable, qui indique toutes les colonnes constituant la clé primaire de DataTable. Si vous connaissez les colonnes de clé primaire dans votre datatable, vous pouvez les parcourir ici. Dans mon cas, puisque toutes mes tables de données connaissent leurs colonnes 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.
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 aimer les disparités. Cela se produit généralement dans vos sprocs et vos 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 de l'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'aucun enregistrement en double n'est renvoyé. Les enregistrements en double peuvent générer des clés primaires en double, ce qui entraînera 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é» précédant les autres. Pour les autres champs, j'ai fourni des données factices, y compris, par exemple, des chaînes de longueur un. Le DAL a déduit le schéma à partir de cet enregistrement initial. Les enregistrements suivants avec des chaînes de longueur 12 ont échoué.
Cela a fonctionné pour moi, source: ici
J'ai eu cette erreur et ce n'était pas lié aux contraintes de DB (du moins dans mon cas). J'ai un fichier .xsd avec une requête GetRecord qui renvoie un groupe d'enregistrements. Une des colonnes de cette table était "nvarchar (512)" et au milieu du projet, je devais la changer en "nvarchar (MAX)".
Tout a bien fonctionné jusqu'à ce que l'utilisateur saisisse plus de 512 sur ce champ et nous commençons à recevoir le fameux message d'erreur "Échec d'activation des contraintes. Une ou plusieurs lignes contiennent des valeurs ne respectant pas les contraintes non nulles, uniques ou de clés étrangères".
Solution: vérifiez toutes les propriétés MaxLength des colonnes de votre DataTable.
La colonne que j'ai changée de "nvarchar (512)" à "nvarchar (MAX)" avait toujours la valeur 512 sur la propriété MaxLength, alors je suis passée à "-1" et ça marche !!.
Le problème vient du concepteur d'accès aux données. Dans Visual Studio, lorsque nous tirons une vue de "l'Explorateur de serveurs" vers la fenêtre du concepteur, elle ajoute une clé primaire sur une colonne de manière aléatoire ou marque quelque chose comme NOT NULL, bien qu'elle soit définie sur null. Bien que la création réelle de la vue dans le serveur de base de données SQL ne définisse pas de clé primaire ni de NOT NULL, le concepteur de VS ajoute cette clé/contrainte.
Vous pouvez le voir dans le concepteur. Une icône représentant une clé se trouve à 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 afficher la liste des propriétés d'une colonne dans le concepteur d'accès aux données VS et modifier les valeurs en conséquence.
Cette erreur était également visible dans mon projet. J'ai essayé toutes les solutions proposées publiées ici, mais sans succès, car le problème n'avait rien à voir avec la taille des champs, la définition des champs de clé de table, les contraintes ou la variable de jeu de données EnforceConstraints.
Dans mon cas, j’ai également un objet .xsd que j’y ai mis lors de la phase de 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 dans la base de données sous-jacente et copie les contraintes dans l'objet Dataset exactement comme vous les avez définies lors de la création des tables dans votre base de données (SQL Server 2008 R2 dans mon répertoire). Cas). Cela signifie que chaque colonne de table créée avec la contrainte "non nulle" ou "clé étrangère" doit également figurer dans le résultat de votre instruction SQL ou de votre procédure stockée.
Après avoir inclus toutes les colonnes de clé et les colonnes définies comme "non nul" dans mes requêtes, le problème a complètement disparu.
Le mien a commencé à fonctionner lorsque j'ai défini AllowDBNull
sur True dans un champ de date d'un tableau de données dans le fichier xsd.
Merci pour toutes les contributions faites jusqu'à présent. Je voudrais juste ajouter que, même si une base de données a été normalisée avec succès, toutes les modifications de schéma apportées à leur application (par exemple, au jeu de données) ou autre, il existe 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ésienne provoquera des enregistrements en double dans la table principale (ou la clé en premier) d'au moins deux tables en cours de liaison . Même si vous spécifiez une clause "Where" dans le code SQL, un élément cartésien peut toujours se produire si JOIN avec une table secondaire, par exemple, contient la jointure inégale (utile pour obtenir des données à partir de 2 tables non liées):
DE tbFirst INNER JOIN tbSystem ON tbFirst.reference_str <> tbSystem.systemKey_str
Solution pour cela: les tables doivent être liées.
Merci. Chagbert
Il n'est pas clair pourquoi exécuter une instruction SELECT implique l'activation de contraintes. Je ne connais pas les technologies C # ou connexes, mais je connais la base de données Informix. Il se passe quelque chose d'étrange avec le système si votre code de requête active (et probablement aussi désactive) les contraintes.
Vous devez également éviter la notation de jointure Informix OUTER démodée et non standard. Sauf si vous utilisez une version incroyablement ancienne d'Informix, vous devez utiliser le style de jointure 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 les suivantes:
AND c.crsnum = e.crsnum
AND c.batch_no = e.batch_no
AND d.lect_code= e.lect_code
C'est une combinaison inhabituelle. Étant donné que 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 cela est correct ou non, mais il est un peu inhabituel de joindre 3 tables de ce type.
Rien de tout cela n'est une réponse définitive à votre problème; Cependant, il peut fournir des indications.
Cela ressemble à une ou plusieurs des colonnes sélectionnées avec:
e.eval, e.batch_no, e.crsnum, e.lect_code, e.prof_course
has AllowDBNull défini sur False dans la définition de votre jeu de données.
J'ai résolu le même problème en changeant ceci de faux en vrai. à la fin je suis allé dans la base de données et changé mon champ de bits pour permettre null, et puis actualisé mon xsd, et actualisé mes wsdl et reference.cs et maintenant tout va bien.
this.columnAttachPDFToEmailFlag.AllowDBNull = true;
* Manière secondaire: *
Si vous n'avez pas besoin de [id] pour être la clé primaire,
Supprimer son attribut de clé primaire:
sur votre DataSet> TableAdapter> cliquez avec le bouton droit sur la colonne [id]> sélectionnez la clé de suppression ...
Le problème sera corrigé.
DirectCast (dt.Rows (0), DataRow) .RowError
Cela donne directement l'erreur
J'ai également eu ce problème et il a été résolu après la modification de * .xsd afin de refléter la taille modifiée de la colonne modifiée dans le serveur SQL sous-jacent.
Je veux juste ajouter une autre raison possible de l'exception à celles énumérées ci-dessus (en particulier pour les personnes qui aiment définir manuellement le schéma de jeu de données):
lorsque, dans votre ensemble de données, vous avez deux tables et qu'il existe une relation (DataSet.Reletions.Add()
) définie à partir du champ de la première table (chfield
) avec le champ de la seconde table (pfield
), une contrainte implicite est ajoutée à ce champ pour être unique même s'il n'est pas spécifié explicitement comme tel dans votre définition, ni comme unique ni comme clé primaire.
Par conséquent, si vous avez des lignes avec des valeurs répétitives dans ce champ parent (pfield
), vous obtiendrez également cette exception.
J'ai résolu ce problème en ouvrant le fichier .xsd avec un lecteur XML et en supprimant une contrainte imposée sur l'un de mes points de vue. Pour une raison quelconque, lorsque j'ai ajouté la vue aux données, il a ajouté une contrainte de clé primaire à l'une des colonnes alors qu'il n'y aurait pas dû y en avoir une.
L’autre méthode consiste à ouvrir le fichier .xsd normalement, à regarder la table/vue à l’origine du problème et à supprimer toutes les clés (colonne du clic droit, sélectionnez delete key
) qui ne devraient pas figurer.
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();
}
}
Si vous utilisez le concepteur de jeux de données Visual Studio pour obtenir la table de données, le message d'erreur «Échec d'activation des contraintes» est généré. J'ai rencontré le même problème. Essayez de prévisualiser les données du concepteur de jeu de données lui-même et faites les correspondre avec la table de votre base de données.
Le meilleur moyen de résoudre ce problème consiste à supprimer l'adaptateur de table et à en créer un autre.
Pour corriger cette erreur, j'ai retiré l'adaptateur de table source de problèmes du concepteur de jeu de données, puis enregistré le jeu de données, puis fait glisser une nouvelle copie de l'adaptateur de table depuis l'explorateur de serveur et l'a corrigé