C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

エラーの治し方について

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■97596 / inTopicNo.1)  エラーの治し方について
  
□投稿者/ 白音 (1回)-(2021/06/11(Fri) 11:25:54)

分類:[.NET 全般] 

Micorosoft Visual Studio C# を使って
SQLServer のデータベースの処理を行っています。
以下のようなものを作って呼び出そうとしたのですが
[制約を有効にできませんでした。行に入力できるのは、
NULL 以外の値、一意な値、あるいは外部キーですが、
この制約の違反が1つ以上の行で発生しています。]
というエラーが発生します。

SELECT	( 
 SELECT	COUNT(*)
 FROM	TBL
 WHERE	COD = @CODE 
 ) AS WKCNT, 
 ISNULL (( 
 SELECT TOP(1) WKNO 
 FROM  	TBL 
 WHERE	COD = @CODE 
 ), 0) AS WKNO

それと、生成するメソッドの選択で
・DataTable にデータを格納する
・DataTable を返す
この2つの違いについても教えていただけませんか?


引用返信 編集キー/
■97597 / inTopicNo.2)  Re[1]: エラーの治し方について
□投稿者/ WebSurfer (2261回)-(2021/06/11(Fri) 11:45:34)
No97596 (白音 さん) に返信

DB がどうなっているか第三者には不明ですので的を得た回答は難しいです。

Microsoft が提供するサンプルデーターベースの Northwind とか Pubs とか
AdventureWorks などから質問者さんのケースに近いテーブルを探して、それ
をベースに話ができませんか?
引用返信 編集キー/
■97599 / inTopicNo.3)  Re[1]: エラーの治し方について
□投稿者/ 魔界の仮面弁士 (3126回)-(2021/06/11(Fri) 13:55:47)
No97596 (白音 さん) に返信
> エラーの治し方について
治す → 直す、かな。


> それと、生成するメソッドの選択で
> ・DataTable にデータを格納する
> ・DataTable を返す
> この2つの違いについても教えていただけませんか?
型付 DataSet のことでしょうか。

両者は一方のみを用意することもできますし、両方を組み込んでも構いません。
使う際に便利な組み合わせとして、お好みで選んでください。


前者は、Fill メソッドに属するもので、
 var ds = new 対象DataSet()
 adapter.FillHoge( ds.対象DataTable, パラメーター);
あるいは
 var tbl = new 対象DataTable();
 adapter.FillHoge( tbl, パラメーター);
の構文で生成されます。
リレーションを持たせた場合など、複数のテーブルを含んだ DataSet を
return したいような場面で使います。

一方後者は、Get メソッドに属するもので
 対象Table tbl = adapter.GetHoge(パラメーター);
の構文となり、常に新しいテーブルを返します。
この場合、特に何もしなければ、tbl.DataSet は null になります。


どちらを使っても良いですし、単独で返したい場合は Get だけでも構いませんが、
自分の場合は、両方または Fill のみとすることが多いです。

そもそも、TableAdapter の元となる DataAdapter には、そもそも Fill しか
存在していないため、Fill さえあれば、Get の代用にすることができます。



> [制約を有効にできませんでした。行に入力できるのは、
> NULL 以外の値、一意な値、あるいは外部キーですが、
> この制約の違反が1つ以上の行で発生しています。]
> というエラーが発生します。

これが発生するという事は、データべースへの SQL 実行は正しく行われたものの、
受け取ったデータを DataTable に格納してみたら、DataTable の制約に合致しなかったという事を示します。

取得されるデータが複数行あって、どの行が制約違反になっているか分からない場合には、
DataSet のエラー検出機構を通じて、問題の発生した行・列を特定できます。

 DataTable tbl = ds.Tables[テーブル名];
 ds.EnforceConstraints = false; // 制約チェックを無効にする
 adapter.Fill( tbl ); // データを取得
 try {
  ds.EnforceConstraints = true; // 制約チェックを再開して例外を捉える
 } catch (System.Data.ConstraintException e) {
  System.Diagnostics.Trace.WriteLine(e.ToString());
  // 制約エラーになった行を列挙
  foreach (var row in tbl.GetErrors()) {
   System.Diagnostics.Trace.WriteLine(row.RowError);
  // 制約エラーになった列を列挙
   foreach (var col in row.GetColumnsInError()) {
    System.Diagnostics.Trace.WriteLine(row.GetColumnError(col));
   }
  }
 }


制約エラーが発生する要因としては、

・主キー競合。
 DataTable の主キー設定が間違っていたとか、あるいは、
 TableAdapter の ClearBeforeFill プロパティを true にせずに、
 既存の(既存行を含む)テーブルに受け取ってしまったとか。

・列指定漏れ。
 SQL で SELECT していないフィールドが DataTable の列として存在しており、
 かつ、DataColumn の AllowDBNull が False になっていた場合など。

・列の型の誤りやサイズ超過
 DataTable の列に対して MaxLength が設定されていて、
 SQL から返されれる列値が、そのサイズを上回る長さになっていた場合など。

などがあります。

引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ