この答えは少しとりとめのないかもしれません...
オラクルは、セット操作に非常にうるさいです。すべての列は、2 番目、3 番目などのクエリの対応する列と同じデータ型である必要があります。
Oracleはを実行する前に数値として評価しますが、実行後に「null-ness」を評価するため、2番目のクエリは失敗すると思います。最初の値が「null-ness」について評価され、次に が発生するため、最初のクエリは成功します。これは、評価の順序が次のとおりであることを意味します。to_number()
union
union
- 第1選択機能
- 最初に選択するデータ型
- セカンドセレクト機能
- 連合
- 2 番目に選択するデータ型
これを段階的に証明しようとしますが、絶対的な証明になるかどうかはわかりません.
次の両方のクエリ
select 1 from dual union select '1' from dual;
select '1' from dual union select 1 from dual;
暗黙的な変換が行われないため、次のエラーで失敗します。
ORA-01790: 式は、対応する式と同じデータ型である必要があります
ただし、次の両方が成功します
select null from dual union select '1' from dual;
select null from dual union select 1 from dual;
これら 2 つのクエリのいずれかを選択するdump
と、次のものが返されます。
SQL> select dump(a)
2 from ( select null a from dual union select '1' from dual );
DUMP(A)
-------------------------------------------------------------------
Typ=96 Len=1: 49
NULL
SQL> select dump(a)
2 from ( select null a from dual union select 1 from dual );
DUMP(A)
-------------------------------------------------------------------
Typ=2 Len=2: 193,2
NULL
ご覧のとおり、列には異なるデータ型があります。文字を使用した最初のクエリは achar
を返し、2 番目のクエリは数値を返しますが、順序が逆になり、2 番目select
が最初になります。
最後に、dump
最初のクエリを見ると
SQL> select substr(dump(ename),1,35) a, substr(dump(loc),1,35) b
2 from ( select ename,to_number(null) as loc from emp
3 union
4 select to_char(null),loc from dept
5 );
A B
----------------------------------- -----------------------------------
Typ=1 Len=6: 104,97,104,97,104,97 NULL
NULL Typ=1 Len=6: 104,97,104,97,104,97
SQL>
dump(to_number(null))
nullであることがわかります。ただし、これは列のデータ型であるため、 avarchar2
ではなく aが返されます。char
返されるステートメントの順序が逆になっておらず、このクエリをテーブルとして作成すると、両方の列がvarchar2
.
選択クエリで列のデータ型を決定するとき、Oracle は最初の既知のデータ型を取得し、それを使用して全体のデータ型を計算します。select
これが、最初のクエリが null だったクエリの行が逆になった理由です。
最初の select はselect ename,to_number(null) from emp
、結果セットがどのようになるかを「説明」するため、最初のクエリは成功します。|varchar2|null|
. 次に、2 番目のクエリで が追加されますが|varchar2|varchar2|
、これにより問題は発生しません。
select ename,to_number(null) from emp
最初の選択で結果セットが として「説明」されるため、2 番目のクエリは失敗しますvarchar2, null
。ただし、null 番号と varchar2 を に追加しようとしますunion
。
ここで信じられないのは、オラクルはそれが前to_number(null)
の数値であると判断し、後まで「null-ness」を評価しないということです。列を使用してオブジェクトを作成することはできず、それを選択することもできないため、これが実際に発生しているかどうかをテストする方法がよくわかりません。union
null
オラクルが許可していないことを証明することはできないので、経験的な証拠を探します。次のクエリの結果 (またはエラー) を検討してください。
SQL> select 1 as a from dual union select to_number(null) from dual;
A
----------
1
SQL> select '1' as a from dual union select to_number(null) from dual;
select '1' as a from dual union select to_number(null) from dual
*
ERROR at line 1:
ORA-01790: expression must have same datatype as corresponding expression
SQL> select 1 as a from dual union select to_char(null) from dual;
select 1 as a from dual union select to_char(null) from dual
*
ERROR at line 1:
ORA-01790: expression must have same datatype as corresponding expression
SQL> select '1' as a from dual union select to_char(null) from dual;
A
-
1
それらは、 null で実行されるかどうかに関係なく、「null-ness」の評価の前に、データ型を暗黙的に定義し、それが a で適切かどうかを評価することを実証しているように見えto_char
ます。to_number
union
この説明は、null である前に数値であるため、coalesce
問題もカバーします。to_number(null)