- PR -

データテーブルのプライマリキーにNULL

1
投稿者投稿内容
adtk
ベテラン
会議室デビュー日: 2004/02/06
投稿数: 75
投稿日時: 2007-02-26 13:12
データテーブルに設定するプライマリキー制約について質問です。
以下のような処理(途中省略)でデータテーブルにプライマリーキーを
設定していますが、dcPkeyで指定する列の中にデータがNULLのものが
存在すると、「列 '[列名]' には Null 値が含まれています。」と
いうエラーが発生してしまいます。プライマリーキーにNULLを格納する
ことは不可能なのでしょうか?

adp
= new System.Data.OleDb.OleDbDataAdapter();
adp.SelectCommand
= new System.Data.OleDb.OleDbCommand([SELECT文],[コネクション]);
dtb
= new System.Data.DataTable("DATA");
dtb.CaseSensitive = true;
adp.Fill(dtb);

System.Data.DataColumn[] dcPkey = new System.Data.DataColumn[5];
「dcPkeyにプライマリキー列を設定する処理」

dtb.PrimaryKey = dcPkey; //エラー箇所
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2007-02-26 13:22
逆に質問しますけど、プライマリ・キーに、
Nullが許容されたりしたら、困ったことになりませんか?
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2007-02-26 13:52
主キー - Wikipedia
http://ja.wikipedia.org/wiki/%E4%B8%BB%E3%82%AD%E3%83%BC

関数従属
http://www.wakhok.ac.jp/biblion/1994/DB/section2.7.5.html
adtk
ベテラン
会議室デビュー日: 2004/02/06
投稿数: 75
投稿日時: 2007-02-26 14:06
・・・そのとおりですね。

データグリッドを使用して、任意のデータベーステーブルの内容を変更するアプリを作成していたのですが、元々はプライマリキーのみで列を特定していたものに対し、プライマリキーが存在しない場合に、ユニークインデックスを列を特定するものとしてプライマリキーのように使用していたため、プライマリキーにNullなどということを言い出してしまいました。ユニークインデックス(一意制約)はデータテーブルに一意制約として設定すれば良いということですね!!

ところで、データテーブルへの一意制約の設定は列のUnique属性をTrueにすれば良いのですよね?複合インデックスであれば全ての列のUnique属性をTrueに?
KI
大ベテラン
会議室デビュー日: 2007/01/10
投稿数: 239
投稿日時: 2007-02-26 15:57
引用:
プライマリキーが存在しない場合に、ユニークインデックスを列を特定するものとしてプライマリキーのように使用していたため



RDBMS側ではプライマリキーではなくただのユニークインデックスで、プライマリキーは存在しない。
プログラム内で編集したデータを、そのユニークインデックスを元にして更新したいという意味と捉えました。

私の考えとしては、やはりレコードの特定にはプライマリキーを使うべきと思いますし、
どうしてもNULLを格納する必要があるのであれば、別にプライマリキーのための列を設けるべきと思います。

もう1つ注意すべき点があります。
RDBMSによってはユニークインデックスの列にNULLのレコードは何レコードでも作成することができます。
(つまりNULLとNULLは重複とみなさないという意味)
そういうRDBMSをお使いの場合、ユニークキーではレコードが特定できない可能性があります。
(例えばOracleはそういう仕様ですが、SQL ServerではNULLであってもエラーになります。)

引用:
ところで、データテーブルへの一意制約の設定は列のUnique属性をTrueにすれば良いのですよね?複合インデックスであれば全ての列のUnique属性をTrueに?


DataTable の Constraints に UniqueConstraint を作成して追加する方法で可能です。
全ての列のUniqueをTrueにすると、それぞれの列で一意になってしまいます。

コード:
dtb.Constraints.Add(new UniqueConstraint(dcPkey);

adtk
ベテラン
会議室デビュー日: 2004/02/06
投稿数: 75
投稿日時: 2007-02-26 18:04
ありがとうございます。
一意制約の設定ができました。

ちなみに、テーブルにプライマリキー持つべきということですが、パッケージシステムへのアドオン機能であるためテーブル構成の変更は不可となっています。

NULLとNULLでの重複データが存在しないかどうかを確認してみます。

ありがとうございました。
末記人
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 233
お住まい・勤務地: あわにこ
投稿日時: 2007-02-26 18:59
引用:

KIさんの書き込み (2007-02-26 15:57) より:
RDBMSによってはユニークインデックスの列にNULLのレコードは何レコードでも作成することができます。



DBMSによってはNULL値はインデックスされないようで...
このことによってインデックス内の一意性が保たれるみたいですねw
KI
大ベテラン
会議室デビュー日: 2007/01/10
投稿数: 239
投稿日時: 2007-02-26 21:55
引用:

KIさんの書き込み (2007-02-26 15:57) より:
RDBMSによってはユニークインデックスの列にNULLのレコードは何レコードでも作成することができます。



すみません。少し勘違いしていました。
調べてみたところ、Oracleでも複合キーの一部の列がNULLだと
重複レコードは登録できないそうです。
例えば5列のキーであれば

1,2,3,4,NULL
1,2,3,4,NULL

はNGですが、

NULL,NULL,NULL,NULL,NULL
NULL,NULL,NULL,NULL,NULL

は登録できるようです。
SQL Serverでは下も登録できないようです。
1

スキルアップ/キャリアアップ(JOB@IT)