teratail header banner
teratail header banner
質問するログイン新規登録

質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.30%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

5432閲覧

sqlでcase式を使ったcheck制約の書き方がわからない

magi201903

総合スコア29

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2020/12/13 14:53

編集2020/12/13 15:10

0

0

前提・実現したいこと

下記テーブルにおいて、女性(Gender列がF)の給料は20万円以下(Salary列が200000以下)、という条件をcheck制約で表現したのが次のSQL文です。

sql

1alter table student 2add constraint check_salary 3check 4(case when Gender = 'F' 5 then case when salary <= 200000 6 then 1 else 0 end 7 else 1 end = 1)

テーブル名:Student
イメージ説明

このSQL文は参考書に書いてあったのを、SqlServer用のSQL文に軽く手直ししたモノです。
だから正常に動きます。

ただわからない点が1つあるのです。
SQL文の末尾にある、「end = 1」の「= 1」 がなぜ必要なのか分かりません。

追記
リンク内容
同じ質問をしている方がいました。しかし、end = 1の =1がなぜ必要なのかは
わからないです。

case 文が長いのですが構造は x = 1 と同じです。x の部分が入れ子の case 式です。

リンク先に上記コメントがありましたが、理解ができません。
end = 1の直前にある記述「else 1」で、「男の場合は1とする。つまり、
制約の対象にはならない」が実現していると思うのです。

試したこと

sql

1alter table student 2add constraint check_salary 3check 4(case when Gender = 'F' 5 then case when salary <= 200000 6 then 1 else 0 end 7    else 1 end)

末尾「=1」を削除した上記SQL文を試すと、次のようなエラーが出ましたが、理解できません。

条件が必要なコンテキストに対し、')' 付近でブール型以外の式が指定されました。

補足情報(FW/ツールのバージョンなど)

sqlservermanagementstudio v18.7.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

CHECK制約はCHECK(式)です。式はbool値(True/False)を返さなければなりません。
ですが、SQLserverにはboolean型はありません。
扱うとしたらbit型です。
面倒なbit型で扱う代わりに、case文での0/1結果と比較する事でbool値を返却するにしているのです。

CHECK 制約

検索条件はブール式によって評価する必要があり、他のテーブルを参照することはできません。

投稿2020/12/13 16:13

編集2020/12/14 16:47
sazi

総合スコア25430

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

magi201903

2020/12/14 16:39

素早い回答ありがとうございました。かっこの中は式でbool値を返す必要があるため、 =1が必要なのですね。 microsoft社のドキュメントにも、下記の記述がありました。 「bool値(True/False)と違って、sqlserverのbit型は、1、0、または NULL の値をとる整数型です。」 https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/bit-transact-sql?view=sql-server-ver15 今回の場合、(bit型) = 1 とすることで、 (bit型が1) = 1のとき  1を返す (bit型が0) = 1のとき  0を返す (bit型がNull) = 1のとき 0を返す。 確かに、bit型がbool値に変換されています。 (select case when x = 0 then 1 else 0 end xに0、1、NULLを入れて実験しました) もし余裕があれば教えてください。 CHECK制約におけるcheck(式)の式はbool値を返す、という仕様はどこかに載っているのでしょうか? 探しても見つからないのです...。 それとも、 「check制約はある列に対してある値が入力できるか否かを決めるから、式は当然bool値を返す 必要がある」という論理から導き出したのでしょうか?
magi201903

2020/12/14 16:50

回答の補強ありがとうございます。公式ドキュメントの中に 「検索条件はブール式によって評価する必要があり」と書いていたのですね。 見落としていました。
guest

0

check制約は万能ではありません。最低限度の指定されたデータ以外を排除するだけです。別にcaseを使うようなチェック機能をSQLで記述するなどが必要かと。

投稿2020/12/13 15:17

Orlofsky

総合スコア16419

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

magi201903

2020/12/14 16:40

回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問