web-dev-qa-db-ja.com

別の列で値がtrueの場合はNULL以外

私はこれに似たテーブルを持っています

create table my_table
(
id serial,
attribute boolean,
number integer
)

number IF attribute値がtrueでnullでないことを強制する方法はありますか?

したがって、レコードが属性値「true」で保存される場合、numberには値を指定する必要があります。

編集:いくつかの掘り下げの後、私はこれを試しました

alter table my_table 
add constraint number_must_have_value CHECK (attribute = 't' and number IS NOT NULL)

それはいくつかの行によって制約に違反していますが、実行すると:

select * from my_table where attribute = 't' and number IS NOT NULL 

0行を取得します。だから私のデータは大丈夫なようです?

とにかくそれを強制するために私は使用しようとします

constraint number_must_have_value NOT VALID CHECK (attribute = 't' and number IS NOT NULL)

しかし、NOT VALIDオプションを機能させることができません。構文エラーが発生します。それは正しい場所にありませんか?

6
geogrow

これはかなり単純なCHECK制約です:

_CREATE TABLE my_table
(
id serial,
attribute boolean,
number integer,
CONSTRAINT if_attribute_then_number_is_not_null 
   CHECK ( (NOT attribute) OR (number IS NOT NULL) ) 
) ;
_

コードの背後にあるロジックは、論理制限_if a then b_がブールロジックで_(not a) or (b)_として記述されていることです。一見すると直感に反するように見えるかもしれませんが、可能なブールの組み合わせを書くとうまくいきます。

制約はCHECK ( NOT (attribute AND number IS NULL) )として記述することもできますが、これはもう少し説明的なように見えるかもしれません("属性をfalseにして、数値を同時にnullにすることはできません")。読みやすいものを選択してください。

15
ypercubeᵀᴹ