Impossibile abilitare i vincoli. Una o più righe contengono valori che violano vincoli non nulli, univoci o con chiave esterna


168

Faccio un join esterno ed eseguo correttamente nel informixdatabase ma ottengo la seguente eccezione nel mio codice:

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

Impossibile abilitare i vincoli. Una o più righe contengono valori che violano vincoli non nulli, univoci o con chiave esterna.

Conosco il problema, ma non so come risolverlo.

La seconda tabella su cui eseguo il join esterno contiene una chiave primaria composita che sono nulli nella precedente query di join esterno.

MODIFICARE:

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

Il problema si verifica con la tabella cc1assiscrseval. La chiave primaria è (batch_no, crsnum, lect_code).

Come risolvere questo problema?


MODIFICARE:

Secondo i @PaulStockconsigli: faccio quello che ha detto e ottengo:

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

Quindi risolvo il mio problema sostituendo e.evala NVL (e.eval,'') eval.e questo risolve il mio problema. Molte grazie.


Quando rimuovo ,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_coursedalla query ogni cosa va bene. qual è il problema per favore.
Anyname Donotcare l'

Esiste anche un bug in ADO.NET in cui un "indice cluster non univoco" creerà un elemento Data.UniqueConstraint errato nel DataTable.
Brain2000,

Risposte:


352

Questo problema è in genere causato da una delle seguenti condizioni

  • valori null restituiti per colonne non impostate su AllowDBNull
  • righe duplicate restituite con la stessa chiave primaria.
  • una discrepanza nella definizione di colonna (ad es. dimensione dei campi char) tra il database e il set di dati

Prova a eseguire la query in modo nativo e osserva i risultati, se il set di risultati non è troppo grande. Se hai eliminato valori nulli, allora suppongo che le colonne della chiave primaria vengano duplicate.

Oppure, per vedere l'errore esatto, è possibile aggiungere manualmente un blocco Try / Catch al codice generato in questo modo e quindi interrompere quando viene sollevata l'eccezione:

inserisci qui la descrizione dell'immagine

Quindi, nella finestra di comando, chiama il GetErrorsmetodo sulla tabella ottenendo l'errore.
Per C #, il comando sarebbe ? dataTable.GetErrors()
Per VB, il comando è? dataTable.GetErrors

inserisci qui la descrizione dell'immagine

Questo ti mostrerà tutti i datarows che hanno un errore. Puoi quindi dare un'occhiata a RowErrorciascuno di questi, che dovrebbe dirti la colonna che non è valida insieme al problema. Quindi, per vedere l'errore del primo datarow in errore il comando è:
? dataTable.GetErrors(0).RowError
o in C # sarebbe? dataTable.GetErrors()[0].RowError

inserisci qui la descrizione dell'immagine


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

4
Eccezionale. Non ha funzionato, ma ho potuto aggiungere un watch per il set di dati e digitare .GetErrors dopo di esso ed espandere i valori. Questo è estremamente utile. Spero di non dimenticarlo prima della prossima volta che ne ho bisogno :)
dwidel,

6
Sì, questo è stato davvero utile - il motivo del mio errore era che la lunghezza del campo era più lunga della lunghezza massima della colonna nell'adattatore della tabella. Una cosa che ho notato è che per raggiungere il punto di interruzione nel file di progettazione, devi andare su Strumenti> Opzioni> Debug e assicurarti che "Abilita solo il mio codice" sia deselezionato. Ti permetterà quindi di scorrere il codice del file designer.
e-on

1
Grazie @PaulStock per la tua risposta. Ho risolto il mio stesso problema.
Uday

1
Questo è stato estremamente utile, ho riscontrato una discrepanza tra la lunghezza della colonna di dati: è stata aumentata nel database e non nel set di dati.
Rob,

38

È possibile disabilitare i vincoli sul set di dati. Ti consentirà di identificare i dati errati e di aiutarti a risolvere il problema.

per esempio

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

Il metodo di riempimento potrebbe essere leggermente diverso per te.


1
Questo mi ha aiutato a trovare i dati che causavano il mio problema, che non erano "dati errati", ma piuttosto cattivi comportamenti della procedura guidata di configurazione dell'origine dati. Apparentemente non sta ottenendo i vincoli di colonna modificati (e mi manca una tabella aggiunta per l'avvio), nonostante uscire e parlare con il DB ... e con la cache non abilitata.
fortboise,

Grazie per questa risposta Avevo un problema con distinzione tra maiuscole e minuscole e dovevo solo impostarlo in modo appropriato nel set di dati.
Dan

10

Questo troverà tutte le righe nella tabella che hanno errori, stampa la chiave primaria della riga e l'errore che si è verificato su quella riga ...

Questo è in C #, ma convertirlo in VB non dovrebbe essere 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);
     }
  }

Oops - mi dispiace PKColumns è qualcosa che ho aggiunto quando ho esteso DataTable che mi dice tutte le colonne che compongono la chiave primaria di DataTable. Se conosci le colonne Chiave primaria nel tuo datatable, puoi farle scorrere qui. Nel mio caso, dal momento che tutti i miei database conoscono i loro cols PK, posso scrivere il debug per questi errori automaticamente per tutte le tabelle.

L'output è simile al seguente:

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

Se sei confuso sulla sezione PKColumns sopra: questo stampa i nomi e i valori delle colonne e non è necessario, ma aggiunge utili informazioni per la risoluzione dei problemi per identificare quali valori di colonna potrebbero causare il problema. Rimuovendo questa sezione e mantenendo il resto verrà comunque stampato l'errore SQLite generato, che noterà la colonna che presenta il problema.


1
Modo geniale per scoprire esattamente dove è andato storto. Mi ha aiutato totalmente a risolvere problemi insondabili in una soluzione che ho ereditato in presenza di incongruenze con i dati. Anche se si trovava su un DataSet e ho appena ripetuto ogni tabella, quindi ogni riga. +10 se potessi.
Andez,

Questo ha funzionato per me. Era un Column 'MyColumn' does not allow DBNull.Value, ma non lo avrebbe mostrato in nessun altro modo. Grazie :)
Alex,

7
  • Assicurarsi che i campi indicati nella query dell'adattatore della tabella corrispondano a quelli della query definita. Il DAL non sembra amare i disallineamenti. Questo in genere accade agli sprocs e alle query dopo aver aggiunto un nuovo campo a una tabella.

  • Se è stata modificata la lunghezza di un campo varchar nel database e l'XML contenuto nel file XSS non lo ha rilevato, trovare il nome del campo e la definizione dell'attributo nell'XML e modificarlo manualmente.

  • Rimuovere le chiavi primarie dagli elenchi selezionati nelle schede di tabella se non sono correlate ai dati restituiti.

  • Eseguire la query in SQL Management Studio e assicurarsi che non vengano restituiti record duplicati. I record duplicati possono generare chiavi primarie duplicate che causeranno questo errore.

  • I sindacati SQL possono sillabare problemi. Ho modificato un adattatore da tavolo aggiungendo un record "selezionare un dipendente" che precede gli altri. Per gli altri campi ho fornito dati fittizi tra cui, ad esempio, stringhe di lunghezza uno. Il DAL ha dedotto lo schema da quel record iniziale. I record seguenti con stringhe di lunghezza 12 non sono riusciti.


1
Benvenuto in SO, Bob. Ho modificato la tua risposta (ancora in revisione, però). Ad esempio, preferiamo non avere i saluti e le firme nelle risposte (è considerato "rumore", consulta le FAQ). Il tuo nome e gravatar mostreranno sempre sotto la risposta comunque.
Christoffer Lette,

5

Questo ha funzionato per me, fonte: qui

Ho avuto questo errore e non era correlato ai vincoli del DB (almeno nel mio caso). Ho un file .xsd con una query GetRecord che restituisce un gruppo di record. Una delle colonne di quella tabella era "nvarchar (512)" e nel mezzo del progetto avevo bisogno di cambiarlo in "nvarchar (MAX)".

Tutto ha funzionato bene fino a quando l'utente non ha inserito più di 512 in quel campo e iniziamo a ricevere il famoso messaggio di errore "Impossibile abilitare i vincoli. Una o più righe contengono valori che violano vincoli non nulli, univoci o con chiave esterna".

Soluzione: controllare tutte le proprietà MaxLength delle colonne in DataTable.

La colonna che ho modificato da "nvarchar (512)" a "nvarchar (MAX)" aveva ancora il valore 512 nella proprietà MaxLength, quindi ho cambiato in "-1" e funziona !!.


Anche il mio problema deve essere stato MaxLength. Uso il designer di set di dati VWD 2010. La tabella di origine è stata modificata da qualcun altro. Ho modificato la query SQL in select *, pensando che avrebbe aggiornato tutte le colonne, ma a quanto pare non ha aggiornato le lunghezze esistenti. Quindi ho modificato la query per selezionare un campo, ho salvato il file .xsd, ho aperto il file .xsd in Notepad ++ per verificare che tutte le definizioni MaxLength tranne una fossero scomparse, quindi ho modificato nuovamente la query in select *. CHE ha rinfrescato MaxLengths e mi ha fatto superare questo errore.
Mark Berry,

Grazie mille, mi sono grattato la testa per tutto il giorno mentre tutto tornava bene. Ho anche dovuto passare a nvarchar (MAX), ma DataTable aveva mantenuto MaxLength a 10! Ti devo qualcosa da bere!
Jon D,

4

Il problema riguarda il progettista dell'accesso ai dati. In Visual Studio, quando si estrae una vista da "Esplora server" nella finestra di Designer, si sta aggiungendo una chiave primaria su una colonna in modo casuale o contrassegnando qualcosa su un valore NULL sebbene sia effettivamente impostato su null. Sebbene la creazione della visualizzazione effettiva nel server db SQL non abbia alcuna chiave primaria definita o NOT NULL definito, il progettista VS sta aggiungendo questa chiave / vincolo.

Puoi vederlo nel designer: è mostrato con un'icona chiave a sinistra del nome della colonna.

Soluzione: fare clic con il tasto destro sull'icona della chiave e selezionare "Elimina chiave". Questo dovrebbe risolvere il problema. È inoltre possibile fare clic con il pulsante destro del mouse su una colonna e selezionare "Proprietà" per visualizzare l'elenco delle proprietà di una colonna nella finestra di progettazione dell'accesso ai dati VS e modificare i valori in modo appropriato.


3

Questo errore si stava manifestando anche nel mio progetto. Ho provato tutte le soluzioni proposte pubblicate qui, ma senza fortuna perché il problema non aveva nulla a che fare con la dimensione dei campi, la definizione dei campi chiave della tabella, i vincoli o la variabile del set di dati EnforceConstraints.

Nel mio caso ho anche un oggetto .xsd che ho messo lì durante la fase di progettazione (il livello di accesso ai dati). Quando trascini gli oggetti della tabella del database nell'elemento visivo del set di dati, legge ogni definizione di tabella dal database sottostante e copia i vincoli nell'oggetto del set di dati esattamente come li hai definiti quando hai creato le tabelle nel tuo database (SQL Server 2008 R2 in my Astuccio). Ciò significa che ogni colonna della tabella creata con il vincolo "non null" o "chiave esterna" deve essere presente anche nel risultato dell'istruzione SQL o della procedura memorizzata.

Dopo aver incluso tutte le colonne chiave e le colonne definite come "non null" nelle mie query, il problema è scomparso completamente.


3

Il mio ha iniziato a funzionare quando ho impostato AllowDBNullTrue su un campo data in una tabella di dati nel file xsd.


2

Sembra forse una o più delle colonne selezionate con:

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

AllowDBNull è impostato su False nella definizione del set di dati .


Metto consentire null = true per tutte le colonne di questa tabella ma invano.
Anyname Donotcare l'

2

Non è chiaro il motivo per cui l'esecuzione di un'istruzione SELECT dovrebbe comportare l'abilitazione di vincoli. Non conosco C # o tecnologie correlate, ma conosco il database Informix. C'è qualcosa di strano nel sistema se il tuo codice di query abilita (e presumibilmente anche disabilita) i vincoli.

Dovresti anche evitare la notazione di join Informix OUTER vecchio stile e non standard. A meno che non si stia utilizzando una versione incredibilmente vecchia di Informix, è necessario utilizzare lo stile di join SQL-92.

La tua domanda sembra menzionare due join esterni, ma ne mostri solo uno nella query di esempio. Anche questo è un po 'sconcertante.

Le condizioni di unione tra ' e' e il resto delle tabelle sono:

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

Questa è una combinazione insolita. Dal momento che non abbiamo il sottoinsieme rilevante dello schema con i relativi vincoli di integrità referenziale, è difficile sapere se questo è corretto o meno, ma è un po 'insolito unire tra 3 tabelle del genere.

Niente di tutto questo è una risposta definitiva al tuo problema; tuttavia, può fornire alcune indicazioni.


2

Grazie per tutti gli input fatti finora. Voglio solo aggiungere che mentre uno potrebbe aver correttamente normalizzato DB, aggiornato eventuali modifiche dello schema alla loro applicazione (ad esempio al set di dati) o giù di lì, c'è anche un'altra causa: sql prodotto CARTESIAN (quando si uniscono le tabelle nelle query).

L'esistenza di un risultato della query cartesiana comporterà la duplicazione di record nella tabella primaria (o prima chiave) di due o più tabelle. Anche se si specifica una clausola "Where" nell'SQL, può ancora verificarsi un cartesiano se JOIN con una tabella secondaria, ad esempio, contiene l'unione disuguale (utile quando ottenere dati da 2 o più tabelle non correlate):

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

Soluzione per questo: le tabelle dovrebbero essere correlate.

Grazie. chagbert


1

Ho risolto lo stesso problema cambiando questo da falso a vero. alla fine sono andato nel database e ho modificato il mio campo bit per consentire null, quindi ho aggiornato il mio xsd e ho aggiornato il mio wsdl e reference.cs e ora tutto va bene.

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

1

Breve e semplice assunzione:

Vai a MSSQL Studio Sever;

Esegui la query della causa di questo errore: nel mio caso vedo che il valore ID era nullo perché dimentico di impostare l' incremento della specifica di identità di 1.

inserisci qui la descrizione dell'immagine

Quindi, immetti 1 per il campo ID in quanto è autoincremano e modifica non consentire NULLS in vista desing

inserisci qui la descrizione dell'immagine

Questo è stato l'errore che ha causato l'errore di lancio del mio adattatore bindingsource e tabel a questo codice:

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

0

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

Questo dà direttamente l'errore


2
Un buon suggerimento, ma funziona solo se è la prima riga del datatable a contenere l'errore, no? Se vengono restituite 100 righe valide e quindi 1 riga errata, non ci sarà un RowErrorattivo Rows(0), vero?
PaulStock,

0

Se si utilizza il designer del set di dati di Visual Studio per ottenere la tabella dei dati, viene visualizzato l'errore "Impossibile abilitare i vincoli". Ho riscontrato lo stesso problema, provare a visualizzare in anteprima i dati dal designer stesso del set di dati e abbinarli alla tabella all'interno del database.

Il modo migliore per risolvere questo problema è eliminare l'adattatore da tavolo e crearne uno nuovo.


0

* Modo secondario: *


Se non hai bisogno di [id] per essere come chiave primaria,

Rimuovi il suo attributo chiave primaria:

sul tuo DataSet> TableAdapter> fai clic con il tasto destro sulla colonna [id]> seleziona Elimina chiave ...

Il problema verrà risolto.


0

Ho anche avuto questo problema ed è stato risolto dopo aver modificato * .xsd per riflettere la dimensione rivista della colonna modificata nel server SQL sottostante.


0

Per correggere questo errore, ho tolto l'adattatore di tabella problematica dal designer del set di dati, ho salvato il set di dati, quindi ho trascinato una nuova copia dell'adattatore di tabella da Esplora server e questo è stato risolto


0

Ho risolto questo problema aprendo il file .xsd con un lettore XML ed eliminando un vincolo posto su una delle mie viste. Per qualsiasi motivo, quando ho aggiunto la vista ai dati, ha aggiunto un vincolo di chiave primaria a una delle colonne quando non ci sarebbe dovuto essere uno.

L'altro modo è quello di aprire normalmente il file .xsd, guardare la tabella / vista che causa il problema ed eliminare eventuali chiavi (colonna del tasto destro, selezionare delete key) che non dovrebbero esserci.


0

Voglio solo aggiungere un altro possibile motivo dell'eccezione a quelli sopra elencati (specialmente per le persone a cui piace definire manualmente lo schema del set di dati):

quando nel tuo set di dati hai due tabelle e c'è una relazione ( DataSet.Reletions.Add()) definita dal campo della prima tabella ( chfield) al campo della seconda tabella ( pfield), c'è come un vincolo implicito aggiunto a quel campo per essere univoco anche se potrebbe non esserlo specificato come esplicitamente nella tua definizione né come unico né come chiave primaria.

Di conseguenza, se si hanno righe con valori ripetitivi in ​​quel campo genitore ( pfield) si otterrà anche questa eccezione.


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

Ho ricevuto lo stesso tipo di errore e nel mio caso lo ha risolto rimuovendo i campi selezionati e sostituendoli con un *. Non ho idea del perché stesse accadendo. La query non aveva errori di battitura o niente di speciale.

Non è la soluzione migliore ma nient'altro ha funzionato e mi stavo esaurendo.

Nella mia ricerca di una risposta chiara ho trovato questo su questo: https://www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont

Soluzione 8

Questo errore si è manifestato anche nel mio progetto, utilizzando Visual Studio 2010. Ho provato altre soluzioni pubblicate in altri blog, ma non ho avuto fortuna perché il problema non aveva nulla a che fare con la dimensione dei campi, la definizione dei campi chiave della tabella, i vincoli o la EnforceConstraintsvariabile del set di dati.

Nel mio caso ho un oggetto .xsd che ho messo lì durante il tempo di progettazione del progetto (nel livello di accesso ai dati). Quando si trascinano gli oggetti della tabella del database nell'elemento visivo del set di dati, legge ogni definizione di tabella dal database sottostante e copia i vincoli nelDataset nell'oggetto esattamente come li hai definiti quando hai creato le tabelle nel tuo database (nel mio caso SQL Server 2008 R2 ). Ciò significa che ogni colonna della tabella creata con il vincolo "non null" o "chiave esterna" deve essere presente anche nel risultato dell'istruzione SQL o della procedura memorizzata.

Dopo aver incluso tutte le colonne vincolate (non null, chiave primaria, chiave esterna, ecc.) Nelle mie query, il problema è scomparso completamente.

Forse non è necessario che tutte le colonne della tabella siano presenti nel risultato della query / procedura memorizzata, ma poiché i vincoli vengono comunque applicati, l'errore viene visualizzato se nel risultato non viene visualizzata una colonna vincolata.

Spero che questo aiuti qualcun altro.


-1

Nel mio caso questo errore è stato provocato da una dimensione di una colonna stringa. Ciò che era strano era quando eseguivo la stessa identica query in uno strumento diverso, non c'erano valori ripetuti né valori nulli.

Poi ho scoperto che la dimensione di una colonna della stringa era 50, quindi quando ho chiamato il metodo di riempimento il valore è stato tagliato, generando questa eccezione.
Faccio clic sulla colonna e imposto nelle proprietà la dimensione su 200 e l'errore era sparito.

Spero che questo aiuto


-1

Ho risolto questo problema facendo "subselect" in questo modo:

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

Quando lo fai su mysql, tutte le proprietà dei collunms (uniche, non nulle ...) verranno cancellate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.