制約を有効にできませんでした。1つ以上の行に、null以外、一意、または外部キーの制約に違反する値が含まれています


168

外部結合を作成し、informixデータベースで正常に実行しましたが、コードで次の例外が発生します。

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

制約を有効にできませんでした。1つ以上の行に、null以外、一意、または外部キーの制約に違反する値が含まれています。

私は問題を知っていますが、それを修正する方法がわかりません。

私が外部結合を行う2番目のテーブルには、前の外部結合クエリではnullである複合主キーが含まれています。

編集:

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

問題はテーブルで発生しますcc1assiscrseval。主キーは(batch_no、crsnum、lect_code)です。

この問題を解決する方法は?


編集:

@PaulStockアドバイスによると:私は彼が言ったことをします、そして私は得ます:

?dt.GetErrors()[0] {System.Data.DataRow} HasErrors:true ItemArray:{object [10]} RowError: "列 'eval'はDBNull.Valueを許可しません。"

だから、に置き換えるe.evalことで問題を解決し NVL (e.eval,'') evalます。これで私の問題が解決します。どうもありがとう。


,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_courseクエリから削除すると、すべてがうまくいきます。問題は何ですか。
Anyname Donotcare 2011

また、ADO.NETには、「一意でないクラスター化インデックス」が誤ったData.UniqueConstraintアイテムをDataTableに作成するというバグがあります。
Brain2000、18年

回答:


352

この問題は通常、次のいずれかが原因で発生します

  • AllowDBNullに設定されていない列にnull値が返される
  • 同じ主キーで返される重複行。
  • データベースとデータセットの間の列定義の不一致(たとえば、charフィールドのサイズ)

結果セットが大きすぎない場合は、クエリをネイティブで実行して結果を確認してください。null値を削除した場合、主キー列が複製されていると思います。

または、正確なエラーを確認するには、生成されたコードにTry / Catchブロックを手動で追加し、例外が発生したときに中断します。

ここに画像の説明を入力してください

次に、コマンドウィンドウ内で、GetErrorsエラーが発生しているテーブルのメソッドを呼び出します。
C#の場合、コマンドは? dataTable.GetErrors()
VBの場合、コマンドは? dataTable.GetErrors

ここに画像の説明を入力してください

これにより、エラーのあるすべてのデータ行が表示されます。次にRowError、これらのそれぞれについてを確認すると、問題とともに無効な列がわかります。したがって、エラーの最初のデータ行のエラーを確認するには、コマンドは次のとおりです。
? dataTable.GetErrors(0).RowError
またはC#では次のようになります。? dataTable.GetErrors()[0].RowError

ここに画像の説明を入力してください


4
どうもありがとう 。>? dt.GetErrors()[0] {System.Data.DataRow} HasErrors: true ItemArray: {object[10]} RowError: "Column 'eval' does not allow DBNull.Value."
Anyname Donotcare 2011

4
驚くばかり。それは機能しませんでしたが、データセットのウォッチを追加し、その後に.GetErrorsと入力して値を展開することができました。それは非常に便利です。次回は必要になる前に、忘れないようにしたいと思います。)
dwidel '26 / 07/26

6
はい、これは本当に役に立ちました。私のエラーの原因は、フィールドの長さがテーブルアダプターの列のmaxLengthよりも長いことでした。気づいたことの1つは、デザイナーファイルのブレークポイントに到達するには、[ツール]> [オプション]> [デバッグ]に移動し、[コードのみを有効にする]がオフになっていることを確認する必要があることです。その後、デザイナーファイルのコードをステップ実行できます。
e-on

1
@PaulStockに回答いただきありがとうございます。同じ問題を解決しました。
2016年

1
これは非常に便利でした。データ列の長さの不一致が見つかりました-データベースでは増加し、データセットでは増加しませんでした。
ロブ

38

データセットの制約を無効にすることができます。これにより、不良データを特定し、問題の解決に役立ちます。

例えば

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

塗りつぶし方法は少し異なる場合があります。


1
これは、問題の原因となっているデータを見つけるのに役立ちました。これは、「悪いデータ」ではなく、データソース構成ウィザードの悪い動作でした。外出してDBと通信しているにもかかわらず、キャッシュが有効になっていないにもかかわらず、列の制約が修正されていない(そして起動するための追加のテーブルがない)ようです。
fortboise 2012

この回答をありがとう。大文字と小文字を区別する問題があり、それをデータセットで適切に設定する必要がありました。
Dan

10

これにより、エラーのあるテーブル内のすべての行が検索され、行の主キーとその行で発生したエラーが出力されます...

これはC#ですが、VBへの変換は難しくありません。

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

おっと-申し訳ありませんがPKColumnsは、DataTableを拡張したときに追加したもので、DataTableの主キーを構成するすべての列を教えてくれます。データテーブルの主キー列がわかっている場合は、ここでループできます。私の場合、すべてのデータテーブルがPK列を知っているので、すべてのテーブルに対してこれらのエラーのデバッグを自動的に作成できます。

出力は次のようになります。

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

上記のPKColumnsセクションについて混乱している場合-これは列の名前と値を出力するため、必要ありませんが、問題を引き起こしている可能性のある列の値を特定するための役立つトラブルシューティング情報が追加されます。このセクションを削除して残りを保持すると、SQLiteエラーが生成され、問題のある列が示されます。


1
それがどこでうまくいかなかったかを正確に見つける素晴らしい方法。私が継承したソリューションで、データとの不整合があった場合に、私に不名誉な問題を完全に助けました。それはDataSetにありましたが、私は各テーブル、そして各行を繰り返しました。できれば+10。
Andez、2014年

これでうまくいきました。それはでしたColumn 'MyColumn' does not allow DBNull.Valueが、それ以外の方法を示すことはありませんでした。おかげで:)
アレックス

7
  • テーブルアダプタークエリで指定されたフィールドが、定義したクエリのフィールドと一致することを確認します。DALは不一致を好まないようです。これは通常、新しいフィールドをテーブルに追加した後、sprocとクエリで発生します。

  • データベースのvarcharフィールドの長さを変更し、XSSファイルに含まれるXMLがそれを取得していない場合は、XMLでフィールド名と属性定義を見つけて、手動で変更します。

  • 返されるデータに関連していない場合は、テーブルアダプターの選択リストから主キーを削除します。

  • SQL Management Studioでクエリを実行し、返されるレコードが重複していないことを確認します。重複したレコードは、このエラーの原因となる重複した主キーを生成する可能性があります。

  • SQLユニオンは問題を引き起こす可能性があります。他の前に「従業員を選択してください」レコードを追加して、1つのテーブルアダプタを変更しました。他のフィールドには、たとえば長さ1の文字列を含むダミーデータを指定しました。DALは、その最初のレコードからスキーマを推測しました。長さが12の文字列が続くレコードは失敗しました。


1
SOへようこそ、ボブ。私はあなたの答えを編集しました(ただし、まだレビュー中です)。たとえば、回答に挨拶や署名を含めないことをお勧めします(「ノイズ」と見なされます。FAQを参照してください)。いずれにしても、あなたの名前とグラバターは常に答えの下に表示されます。
クリストファーレッテ

5

これは私のために働いた、ソース:ここ

私にはこのエラーがあり、DBの制約とは関係がありませんでした(少なくとも私の場合)。レコードのグループを返すGetRecordクエリを含む.xsdファイルがあります。そのテーブルの列の1つは「nvarchar(512)」で、プロジェクトの途中で「nvarchar(MAX)」に変更する必要がありました。

ユーザーがそのフィールドに512を超えて入力し、「制約を有効にできませんでした。1つ以上の行に非null、一意、または外部キーの制約に違反する値が含まれています」という有名なエラーメッセージが表示されるまで、すべてが正常に機能しました。

解決策:DataTableの列のすべてのMaxLengthプロパティを確認します。

「nvarchar(512)」から「nvarchar(MAX)」に変更した列のMaxLengthプロパティの値は512のままなので、「-1」に変更して機能します。


私の問題もMaxLengthだったに違いありません。VWD 2010データセットデザイナーを使用しています。ソーステーブルが他のユーザーによって変更されました。SQLクエリをに変更して、select *すべての列を更新すると考えましたが、明らかに既存の長さは更新されませんでした。したがって、クエリを変更して1つのフィールドを選択し、.xsdを保存し、.xsdをNotepad ++で開いて、MaxLength定義の1つを除くすべてがなくなっていることを確認してから、もう一度クエリをに変更しましたselect *。これによりMaxLengthsが更新され、このエラーを回避できました。
Mark Berry

本当にありがとうございました。すべてが正常に報告されていたので、私はこれについて一日中頭を悩ませています。私もnvarchar(MAX)に変更する必要がありましたが、DataTableはMaxLengthを10に保ちました!私はあなたに飲み物を借りています!
Jon D

4

問題は、データアクセスデザイナーにあります。Visual Studioでは、「サーバーエクスプローラ」からデザイナウィンドウにビューをプルすると、列に主キーがランダムに追加されるか、実際にはnullに設定されていますが、NOT NULLに何かがマークされます。SQLデータベースサーバーでの実際のビューの作成では、主キーが定義されていないか、NOT NULLが定義されていませんが、VSデザイナーはこのキー/制約を追加しています。

これはデザイナーで確認できます。列名の左側に鍵のアイコンが表示されます。

解決策:キーアイコンを右クリックして、[キーの削除]を選択します。これで問題が解決するはずです。列を右クリックして[プロパティ]を選択し、VSデータアクセスデザイナーで列のプロパティのリストを表示して、値を適切に変更することもできます。


3

このエラーは私のプロジェクトでも発生していました。私はここに投稿されたすべての提案されたソリューションを試しましたが、問題はフィールドサイズ、テーブルキーフィールドの定義、制約、またはEnforceConstraintsデータセット変数とは何の関係もないため、まったく運がありませんでした。

私の場合、プロジェクトの設計時にそこに配置した.xsdオブジェクト(データアクセスレイヤー)もあります。データベーステーブルオブジェクトをDatasetビジュアルアイテムにドラッグすると、基になるデータベースから各テーブル定義が読み取られ、データベースにテーブルを作成したときに定義したとおりに制約がDatasetオブジェクトにコピーされます(SQL Server 2008 R2場合)。つまり、「null以外」または「外部キー」の制約で作成されたすべてのテーブル列は、SQLステートメントまたはストアドプロシージャの結果にも存在する必要があります。

すべてのキー列と「null以外」として定義された列をクエリに含めた後、問題は完全になくなりました。



2

おそらく1つ以上の列が選択されているようです:

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

AllowDBNullはに設定Falseにあなたのデータセットdefintionに。


このテーブルのすべての列にallow null = trueを設定しましたが、無駄になりました。
Anyname Donotcare 2011

2

SELECTステートメントの実行に制約の有効化が必要な理由は明らかではありません。C#や関連技術は知りませんが、Informixデータベースは知っています。クエリコードが制約を有効にしている(おそらく無効にしている)場合、システムで何か奇妙なことが起こっています。

また、旧式の非標準のInformix OUTER結合表記法を使用しないでください。Informixの信じられないほど古いバージョンを使用している場合を除き、SQL-92スタイルの結合を使用する必要があります。

あなたの質問は2つの外部結合に言及しているようですが、クエリ例では1つしか表示されていません。それも少し不可解です。

' e'と残りのテーブル間の結合条件は次のとおりです。

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

これは珍しい組み合わせです。関連する参照整合性制約を持つスキーマの関連するサブセットがないため、これが正しいかどうかを知るのは困難ですが、そのような3つのテーブル間を結合するのは少し珍しいことです。

これはあなたの問題に対する決定的な答えではありません。ただし、いくつかのガイダンスが提供される場合があります。


2

これまでに行われたすべての入力に感謝します。私はそれを追加したいだけですが、DBを正常に正規化したり、アプリケーションへのスキーマの変更(データセットなど)を更新したり、SQL CARTESIAN製品(クエリでテーブルを結合する場合)などの別の原因もあります。

デカルトクエリ結果が存在すると、結合されている2つ以上のテーブルのプライマリ(またはキーが最初に)テーブルに重複レコードが発生します。SQLで "Where"句を指定した場合でも、セカンダリテーブルなどのJOINに不等結合が含まれていると、デカルトが発生する可能性があります(2つ以上のUN関連テーブルからデータを取得する場合に便利です)。

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

このための解決策:テーブルを関連付ける必要があります。

ありがとう。Chagbert


1

これをfalseからtrueに変更して、同じ問題を解決しました。最後に、データベースに移動し、ビットフィールドをnullを許可するように変更してから、xsdを更新し、wsdlとreference.csを更新しました。

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

1

短くて簡単な解決策:

MSSQL Studio Severに移動します。

このエラーの原因のクエリを実行します。私の場合、ID仕様の増分を1に設定するのを忘れたため、id値がnullであることがわかります。

ここに画像の説明を入力してください

そのため、IDフィールドに1を入力します。これは自動インクレマンであり、変更して、デザインビューでNULLを許可しません。

ここに画像の説明を入力してください

これが、このコードでbindingsourceおよびtabelアダプターのthrowinエラーを引き起こしたエラーです。

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

0

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

これは直接エラーを与えます


2
良い提案ですが、それはエラーのあるデータテーブルの最初の行である場合にのみ機能しますね。100の良い行が返され、次に1つの悪い行がある場合、RowErroron Rows(0)はありませんか?
PaulStock 2012

0

Visual Studioデータセットデザイナーを使用してデータテーブルを取得している場合、「制約の有効化に失敗しました」というエラーがスローされます。同じ問題に直面しました。データセットデザイナー自体からデータをプレビューし、データベース内のテーブルと照合してみてください。

この問題を解決する最善の方法は、テーブルアダプターを削除して、新しいアダプターを作成することです。


0

*二次的な方法:*


[id]を主キーにする必要がない場合は、

主キー属性を削除します。

DataSet> TableAdapter> [id]列を右クリック> Deleteキーを選択...

問題は修正されます。


0

私にもこの問題があり、*。xsdを変更して、基になるSQLサーバーで変更された列のサイズの変更を反映した後に解決されました。


0

このエラーを修正するために、データセットデザイナーから問題のあるテーブルアダプターを外してデータセットを保存し、サーバーエクスプローラーからテーブルアダプターの新しいコピーをドラッグして修正しました


0

この問題を解決するには、XMLリーダーで.xsdファイルを開き、ビューの1つに配置された制約を削除しました。何らかの理由でデータにビューを追加したとき、列の1つに本来あるべきではないはずの列に主キー制約が追加されました。

もう1つの方法は、.xsdファイルを通常どおりに開き、問題の原因となっているテーブル/ビューを確認して、delete keyそこにあるはずのないキー(列を右クリック、選択)を削除します。


0

上記のリストに例外の考えられる別の理由を追加したいだけです(特に、データセットスキーマを手動で定義したい人のために):

データセットに2つのテーブルがあり、DataSet.Reletions.Add()最初のテーブルのフィールド(chfield)から2番目のテーブルのフィールド(pfield)に関係()が定義されている場合、そのフィールドに暗黙の制約が追加されて一意になるている場合、ではない可能性があります一意でも主キーでもない定義で明示的に指定されている。

結果として、その親フィールド(pfield)に反復的な値を持つ行がある場合、この例外も発生します。


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

同じエラータイプを受け取りましたが、私の場合、選択フィールドを削除して*に置き換えることで解決しました。なぜそれが起こったのか分かりません。クエリにタイプミスや空想はありませんでした。

最善の解決策ではありませんが、他には何も機能せず、疲れ果てていました。

私は明確な答えを探してこれにこれを見つけました:https : //www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont

解決策8

このエラーは、Visual Studio 2010を使用した私のプロジェクトでも表示されていました。他のブログに投稿された他の解決策を試しましたが、問題はフィールドサイズ、テーブルキーフィールドの定義、制約、またはEnforceConstraintsデータセット変数とは関係がないため、まったくうまくいきませんでした。

私の場合、プロジェクトの設計時に(データアクセス層で)配置した.xsdオブジェクトがあります。データベーステーブルオブジェクトをデータセットビジュアルアイテムにドラッグすると、基になるデータベースから各テーブル定義が読み込まDatasetれ、データベースにテーブルを作成したときに定義したとおりに制約がオブジェクトにコピーされます(私の場合はSQL Server 2008 R2)。 )。つまり、「null以外」または「外部キー」の制約で作成されたすべてのテーブル列は、SQLステートメントまたはストアドプロシージャの結果にも存在する必要があります。

すべての制約された列(null、主キー、外部キーなど)をクエリに含めた後、問題は完全になくなりました。

クエリ/ストアドプロシージャの結果にすべてのテーブル列が存在する必要はないかもしれませんが、制約がまだ適用されているため、結果に制約された列が表示されない場合はエラーが表示されます。

これが他の誰かを助けることを願っています。


-1

私の場合、このエラーは文字列列のサイズによって引き起こされました。奇妙だったのは、まったく同じクエリを別のツールで実行したときに、繰り返し値もnull値もなかったことです。

次に、文字列列のサイズが50であることを発見したので、fillメソッドを呼び出したときに値が切り取られ、この例外がスローされました。
列をクリックして、プロパティでサイズを200に設定すると、エラーは発生しなくなりました。

この助けを願っています


-1

私はそれのような「副選択」をすることによってこの問題を解決しました:

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

mysqlでそれを実行すると、すべての列のプロパティ(一意、null以外...)がクリアされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.