Oracle を使用して、列の値が 'YES' または 'NO' の場合、テーブルを制約して、1 つの行だけが 'YES' の値を持つようにすることはできますか?
テーブル構造を再設計したいのですが、これは不可能です。
[UDPATE] 残念ながら、このテーブルでは null 値は許可されていません。
Oracle を使用して、列の値が 'YES' または 'NO' の場合、テーブルを制約して、1 つの行だけが 'YES' の値を持つようにすることはできますか?
テーブル構造を再設計したいのですが、これは不可能です。
[UDPATE] 残念ながら、このテーブルでは null 値は許可されていません。
関数ベースのインデックスを使用します。
create unique index only_one_yes on mytable
(case when col='YES' then 'YES' end);
Oracle は、完全に null ではないキーのみをインデックスに登録します。ここでの CASE 式は、すべての「NO」値が null に変更されるため、インデックスが作成されないようにします。
これは厄介なハックですが、列で NULL が許可されている場合は、"NO" の代わりに NULL を使用し、以前と同じように "YES" を使用できます。その列に一意のキー制約を適用すると、2 つの "YES" 値が得られることはありませんが、それでも多くの NO があります。
更新: @Nick Pierpoint: チェック制約を追加して、列の値が「YES」と NULL のみに制限されるようにすることを提案しました。構文はすべて彼の答えで解決されています。
Tom Kyte の記事で、まさにこの質問と彼の回答を確認してください。
http://tkyte.blogspot.com/2008/05/another-of-day.html
要約: トリガーを使用しない、自律型トランザクションを使用しない、2 つのテーブルを使用する。
Oracle データベースを使用している場合は、AskTom について知り、彼の本を入手する必要があります。
テーブル定義では機能しません。
ただし、ストアド プロシージャを呼び出すトリガーを使用してテーブルを更新すると、1 つの行だけに "YES" が含まれていることを確認できます。
私のコメントから yukondude による以前の回答に続いて、一意のインデックスとチェック制約を追加します。
create table mytest (
yesorno varchar2(3 char)
);
create unique index uk_mytest_yesorno on mytest(yesorno);
alter table mytest add constraint ck_mytest_yesorno check (yesorno is null or yesorno = 'YES');
Oracleはフィルター処理されたインデックスのようなものをサポートしていますか(先週、MSSQL2008などがサポートしていると聞きました)?おそらく、列の値が「Yes」の行にのみ適用される一意のキーを定義できます。
2番目のテーブルを使用して、現在のテーブルの適切な行を指すと思います。他のテーブルを使用して、他の変数の値を格納することもできます。