CHECK制約(追加するデータが指定した条件を満たしているかどうか)

テーブルを作成する時にカラムに対して CHECK 制約をつけると、追加するデータが指定した条件を満たしているかどうかを確認することができます。ここでは PostgreSQL における CHECK 制約の使い方について解説します。

(Last modified: )

CHECK制約の使い方

テーブルを作成するとき、カラムに対して CHECK 制約を設定すると、追加するデータに対する条件を設定することができます。書式は次のとおりです。

CREATE TABLE [ IF NOT EXISTS ] table_name (
  column_name data_type CHECK ( expression ) [, ... ]
)

カラムに対して追加するデータに対する条件式( check(条件式) )を設定します。例えば文字列のカラムであれば追加する値が空文字以外などの条件を設定したり、数値のカラムであれば追加する値が 0 以上であるなどの条件をを設定できます。追加するデータが条件を満たしていなかった場合はエラーとなります。

また CHECK 制約はカラム毎ではなくテーブルに対して設定することもできます。

CREATE TABLE [ IF NOT EXISTS ] table_name (
  column_name1 data_type1, 
  column_name2 data_type2,
  [... ,]
  CHECK ( expression )
)

カラムの定義と分けて記述したい場合や、複数のカラムに対する条件式を記述したい場合などに使用します。

-- --

それでは実際に試してみます。 mydb データベースの myschema スキーマの中に次のようなテーブルを作成しました。

create table myschema.friends (
  id integer check(id > 0), 
  name varchar(10), 
  address varchar(10) check(address <> '')
);

CHECK制約の使い方(1)

今回 id カラムに対して id カラムの値が 0 より大きいとい条件式を設定し、 address カラムに対して address カラムの値が 空文字('') 以外という条件式を設定しています。

psql メタコマンドの \d コマンドを使って作成したテーブルのカラムの情報を取得してみます。

\d myschema.friends

CHECK制約の使い方(2)

欄外にテーブルに対して設定されている CHECK 制約の内容が表示されています。

それではまず問題のないデータを追加してみます。

insert into myschema.friends values (1, 'Yamada', 'Tokyo');

CHECK制約の使い方(3)

正常にデータを追加することができました。

次に id カラムの値が CHECK 制約で偽となるようなデータを追加してみます。

insert into myschema.friends values (-3, 'Suzuki', 'Osaka');

CHECK制約の使い方(4)

id カラムには id > 0 という制約が設定されているため、 ERROR: リレーション"friends"の新しい行は検査制約"friends_id_check"に違反しています というエラーが表示されてデータの追加に失敗しました。

最後に address カラムの値が CHECK 制約で偽となるようなデータを追加してみます。

insert into myschema.friends values (3, 'Honda', '');

CHECK制約の使い方(5)

address カラムには address <> '' という制約が設定されているため、 ERROR: リレーション"friends"の新しい行は検査制約"friends_address_check"に違反しています というエラーが表示されてデータの追加に失敗しました。

このように CHECK 制約を設定することで、事前に設定した条件に一致しない値を持つデータをテーブルに追加できないようにすることができます。

複数のカラムを使った条件式

続いて CHECK 制約の条件式として複数のカラムを使った式を記述してみます。複数のカラムを使用するので、特定のカラムに対してではなくテーブルに対する CHECK 制約を記述します。

それでは実際に試してみます。 mydb データベースの myschema スキーマの中に次のようなテーブルを作成しました。

create table myschema.userpoint (
  name varchar(10), 
  maxpoint integer, 
  minpoint integer, 
  check(maxpoint >= minpoint)
);

複数のカラムを使った条件式(1)

CHECK 制約の条件式として maxpoint カラムの値が minpoint カラムの値よりも等しいか大きいことと設定しています。

最初に問題のないデータを 3 つ追加します。

insert into myschema.userpoint values 
  ('Yamada', 80, 64), 
  ('Suzuki', 92, 78), 
  ('Endou', 84, 84);

複数のカラムを使った条件式(2)

いずれのデータも maxpoint カラムの値が minpoint カラムの値よりも大きいか等しいので問題なくデータを追加することができました。

次に CHECK 制約の条件式が偽となるデータを追加してみます。

insert into myschema.userpoint values ('Takahashi', 75, 82);

複数のカラムを使った条件式(3)

今回のデータは maxpoint カラムの値が minpoint カラムの値よりも小さいため ERROR: リレーション"userpoint"の新しい行は検査制約"userpoint_check"に違反しています というエラーが表示されてデータの追加に失敗しました。

このようにカラムに対する制約ではなくテーブルに対する制約として記述することで、テーブルに含まれる複数のカラムを使った条件式を記述することができます。

-- --

CHECK 制約の使い方について解説しました。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。