AIです。(Artificial Intelligence ではありません)
最近スーパーでマイナーなお肉が売られているのを発見し、ちょっと興味がわいているこの頃です。カンガルー肉…エルク肉…どんなお味なんでしょうか…
さて、今回は 23ai から新たに追加された ブール・データ型やブール式について、見ていきます!
■ブール・データ型(BOOLEAN データ型)とは
表内に TRUE / FALSE で値を格納するデータ型です。このデータ型を使うと SQL 文でブール式を使った条件を指定することができるようになります。
また、TRUE / FALSE に変換可能な文字をブール・データ型の列に格納した場合、自動で TRUE / FALSE に変換されて格納されます。
■文字の自動変換
以下の文字列リテラルをブール・データ型の列に格納した場合、それぞれ以下のように TRUE/FALSE に変換されます。
TRUE FALSE
-------------- --------------
'true' 'false'
'yes' 'no'
'on' 'off'
0以外の数値 '0'
't' 'f'
'y' 'n'
では、実際に表に値を格納してみましょう。
SQL> CREATE TABLE Woodcutter.bool_test (id number(6),value varchar2(100),bool_value boolean);
表が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(1,'TRUE','TRUE'); ★value(VARCHAR2データ型) と bool_value(BOOLEANデータ型)に同じ値を格納
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(2,'FALSE','FALSE');
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(3,'ON','ON');
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(4,'OFF','OFF');
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(5,'1',1);
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(6,'0',0);
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(7,'YES','YES');
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(8,'NO','NO');
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(9,'T','T');
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(10,'F','F');
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(11,'Y','Y');
1行が作成されました。
SQL> INSERT INTO Woodcutter.bool_test VALUES(12,'N','N');
1行が作成されました。
SQL> SELECT * FROM Woodcutter.bool_test;
ID VALUE BOOL_VALUE
---------- ---------- -----------
1 TRUE TRUE
2 FALSE FALSE
3 ON TRUE ★それぞれの値に応じて TRUE / FALSE として格納されています。
4 OFF FALSE
5 1 TRUE
6 0 FALSE
7 YES TRUE
8 NO FALSE
9 T TRUE
10 F FALSE
11 Y TRUE
12 N FALSE
12行が選択されました。
表に記載の通りに ブール・データ型の列は、TRUE / FALSE に変換されました!
■ブール式を使用した SELECT
ブール・データ型の実装と併せて、SQL 内でブール式を使用することができるようになりました。
例えば、先ほど作成した表から BOOL_VALUE が TRUE の値のレコードのみ SELECT したい場合
以下の様に IS TRUE を使って条件を指定することができます。
SQL> SELECT * FROM Woodcutter.bool_test WHERE bool_value IS TRUE;
ID VALUE BOOL_VALUE
---------- ---------- -----------
1 TRUE TRUE
3 ON TRUE
5 1 TRUE
7 YES TRUE
9 T TRUE
11 Y TRUE
6行が選択されました。
IS NOT TRUE を使うこともできます。
SQL> SELECT * FROM Woodcutter.bool_test WHERE bool_value IS NOT TRUE;
ID VALUE BOOL_VALUE
---------- ---------- -----------
2 FALSE FALSE
4 OFF FALSE
6 0 FALSE
8 NO FALSE
10 F FALSE
12 N FALSE
6行が選択されました。
もちろん IS FALSE や IS NOT FALSE も利用可能です。
また、IS をつけなくてもブール・データ型は列名のみを条件として指定することが可能です。この場合、TRUE でないものを選択したい場合、NOT <ブール・データ型の列名>と指定します。
SQL> SELECT * FROM Woodcutter.bool_test WHERE bool_value; ★列名だけの指定
ID VALUE BOOL_VALUE
---------- ---------- -----------
1 TRUE TRUE
3 ON TRUE
5 1 TRUE
7 YES TRUE
9 T TRUE
11 Y TRUE
6行が選択されました。
SQL> SELECT * FROM Woodcutter.bool_test WHERE NOT bool_value;
ID VALUE BOOL_VALUE
---------- ---------- -----------
2 FALSE FALSE
4 OFF FALSE
6 0 FALSE
8 NO FALSE
10 F FALSE
12 N FALSE
6行が選択されました。
■ブール・データ型ではない列に対してブール式を使用
更に、ブール・データ型ではない列に対してもブール式で問合せをすることが可能です。その場合「■文字の自動変換」で記載した文字列に従って TRUE/FALSE が判断されます。
SQL> SELECT * FROM Woodcutter.bool_test WHERE value IS FALSE;
ID VALUE BOOL_VALUE
---------- ---------- -----------
2 FALSE FALSE
4 OFF FALSE
6 0 FALSE
8 NO FALSE
10 F FALSE
12 N FALSE
6行が選択されました。
SQL> SELECT * FROM Woodcutter.bool_test WHERE value;
ID VALUE BOOL_VALUE
---------- ---------- -----------
1 TRUE TRUE
3 ON TRUE
5 1 TRUE
7 YES TRUE
9 T TRUE
11 Y TRUE
6行が選択されました。
これはつまり、dba_users などの静的ディクショナリビューで Y/N や YES/NO で
データが格納されている列に対してもブール式で問合せができるということですね…!
SQL> desc dba_users
名前 NULL? 型
----------------------------------------- -------- ----------------------------
USERNAME NOT NULL VARCHAR2(128)
:
COMMON VARCHAR2(3)★
SQL> SELECT username,common FROM dba_users WHERE common;
USERNAME COM
------------------------- ---
SYS YES
SYSTEM YES
SYSRAC YES
:(一部割愛)
SYSKM YES
SYS$UMF YES
SYSDG YES
33行が選択されました。
■ブール・データ型に変換できないデータの場合
さて、ブール・データ型やブール式の特徴について見てきましたが、次はブール・データ型に変換できないデータが入っていた場合の挙動を確認します。
・ブール・データ型の列に変換できないデータを挿入した場合
SQL> INSERT INTO Woodcutter.bool_test VALUES(13,'AI','I');
INSERT INTO Woodcutter.bool_test VALUES(13,'AI','I')
*
行1でエラーが発生しました。:
ORA-61800: 無効なブール・リテラル: I ヘルプ:
https://docs.oracle.com/error-help/db/ora-61800/
・ブール式で条件指定した列にブール・データ型に変換できないデータが入っていた場合
SQL> SELECT * FROM Woodcutter.bool_test;
ID VALUE BOOL_VALUE
---------- ---------- -----------
1 TRUE TRUE
2 FALSE FALSE
3 ON TRUE
4 OFF FALSE
5 1 TRUE
6 0 FALSE
7 YES TRUE
8 NO FALSE
9 T TRUE
10 F FALSE
11 Y TRUE
12 N FALSE
13 AI TRUE
13行が選択されました。
SQL> SELECT * FROM Woodcutter.bool_test WHERE value;
ERROR:
ORA-61800: 無効なブール・リテラル: AI ヘルプ:
https://docs.oracle.com/error-help/db/ora-61800/
レコードが選択されませんでした。
いずれも ORA-61800 が返されました。
■AND / OR 条件
ブール式での条件を二つ以上組み合わせて AND/OR 条件で絞ることもできます。
SQL> SELECT * FROM Woodcutter.bool_test2;
ID BOOL_VALUE1 BOOL_VALUE2
---------- ----------- -----------
1 TRUE TRUE
2 TRUE FALSE
3 FALSE TRUE
4 FALSE FALSE
SQL> SELECT * FROM Woodcutter.bool_test2 WHERE bool_value1 AND bool_value2;
ID BOOL_VALUE1 BOOL_VALUE2
---------- ----------- -----------
1 TRUE TRUE
SQL> SELECT * FROM Woodcutter.bool_test2 WHERE bool_value1 OR bool_value2;
ID BOOL_VALUE1 BOOL_VALUE2
---------- ----------- -----------
1 TRUE TRUE
2 TRUE FALSE
3 FALSE TRUE
■TO_BOOLEAN 関数
また、ブール・データ型に変換可能なデータであれば、TO_BOOLEAN 関数を使ってブール・データ型として表示させることも可能です。
SQL> SELECT TO_BOOLEAN(1),TO_BOOLEAN('ON'),TO_BOOLEAN('F');
TO_BOOLEAN( TO_BOOLEAN( TO_BOOLEAN(
----------- ----------- -----------
TRUE TRUE FALSE
SQL> SELECT TO_BOOLEAN(1),TO_BOOLEAN('ON'),TO_BOOLEAN('F'),TO_BOOLEAN('I');
SELECT TO_BOOLEAN(1),TO_BOOLEAN('ON'),TO_BOOLEAN('F'),TO_BOOLEAN('I')
*
行1でエラーが発生しました。:
ORA-61800: 無効なブール・リテラル: I ヘルプ:
https://docs.oracle.com/error-help/db/ora-61800/
仮想列で TO_BOOLEAN 関数を使えば既存のデータを BOOLEAN データ型で表示させることも簡単にできます。
SQL> ALTER TABLE Woodcutter.bool_test ADD (fuction_value AS (TO_BOOLEAN(value)));
表が変更されました。
SQL> SELECT * FROM Woodcutter.bool_test;
ID VALUE BOOL_VALUE FUCTION_VAL
---------- --------- ----------- -----------
1 TRUE TRUE TRUE
2 FALSE FALSE FALSE
3 ON TRUE TRUE
4 OFF FALSE FALSE
5 1 TRUE TRUE
6 0 FALSE FALSE
7 YES TRUE TRUE
8 NO FALSE FALSE
9 T TRUE TRUE
10 F FALSE FALSE
11 Y TRUE TRUE
12 N FALSE FALSE
12行が選択されました。
■おわりに
さて、ブール・データ型およびブール式について色々と検証してきましたがいかがでしょうか。
AI的には、ブール・データ型が実装されたことにより、今まで静的ディクショナリビューでTRUE/FALSE で表現できそうなデータに変更が出るのか気になっていましたが、特定の文字列であれば特に意識することなくブール型で条件を指定できることが驚きでした!
今後、調査で静的ディクショナリビューや v$ ビューを見るときの SQL の作り方にも影響しそうですね。