doesは ''をNULL
とみなすことは知っていますが、それは私に伝えることはあまりありませんwhyこれが事実です。 SQL仕様を理解しているように、「」はNULL
と同じではありません。1つは有効なデータであり、もう1つは同じ情報がないことを示しています。
気軽に推測してください。ただし、そうであるかどうかを示してください。 Oracleからコメントできる人がいたら、それは素晴らしいことです!
その答えは、Oracleは非常に古いということだと思います。
SQL標準が登場する前の昔、オラクルはVARCHAR
/VARCHAR2
列の空の文字列はNULL
であり、NULLの意味は1つだけであるという設計上の決定を行いました(求められたことのないデータ、回答は存在するがユーザーが知らないデータ、回答のないデータなどを区別するリレーショナル理論家です。これらはすべてNULL
の感覚を構成します。 。
SQL標準が登場し、NULL
と空の文字列が別個のエンティティであることに同意するまでに、2つが同等であると想定したコードを持つOracleユーザーがすでに存在していました。そのため、Oracleには、基本的に、既存のコードを壊す、SQL標準に違反する、または潜在的に多数のクエリの機能を変更する何らかの初期化パラメーターを導入するオプションが残されていました。 SQL標準(IMHO)に違反することは、これら3つのオプションの中で最も破壊的ではありませんでした。
Oracleは、SQL標準に準拠するために、将来のリリースでVARCHAR
データ型が変更される可能性を残しました(そのため、誰でもOracleでVARCHAR2
を使用します。今後も同じ)。
Tom Kyte OracleのVP:
ゼロ長のvarcharはNULLとして扱われます。
''はNULLとして扱われません。
'' char(1)に割り当てられると ''になります(char型は空白が埋め込まれた文字列です)。
'' varchar2(1)に割り当てられると ''になります ''これは長さゼロの文字列であり、長さゼロの文字列はOracleではNULLです(長すぎない '')
Oracleを初期の開発者がたぶんそうしていたように、データ入力システムの栄光あるバックエンドとして考えるなら、これはもっと理にかなっていると思います。データベース内のすべてのフィールドは、データ入力オペレーターが画面で見たフォームのフィールドに対応していました。オペレーターがフィールドに何も入力しなかった場合、それが「生年月日」であろうと「住所」であろうと、そのフィールドのデータは「不明」です。オペレーターが誰かのアドレスが実際に空の文字列であることを示す方法はありません。それはとにかくあまり意味がありません。
Oracleのドキュメントは、少なくともバージョン7まで遡って、開発者にこの問題を警告しています。
Oracleは、「不可能な値」手法によってNULLを表すことを選択しました。たとえば、数値の場所のNULLは、不可能な値である「マイナスゼロ」として格納されます。計算結果のマイナスゼロは、保存される前に正のゼロに変換されます。
また、Oracleは誤って、長さ0のVARCHAR文字列(空の文字列)を不可能な値と見なし、NULLを表すための適切な選択肢を選択しました。空の文字列は不可能な値にはほど遠いことがわかります。それは文字列連結の操作下のアイデンティティです!
Oracleのドキュメントは、Oracleの将来のバージョンでは、空の文字列とNULLの間のこの関連付けが壊れ、その関連付けに依存するコードが壊れる可能性があることをデータベース設計者および開発者に警告します。
不可能な値以外にもNULLにフラグを立てる手法がありますが、Oracleはそれらを使用しませんでした。
(行と列の交差を意味するために、上記の「場所」という言葉を使用しています。)
空の文字列は、2つ(空の文字列とnull)が同じではない状況と比較した場合、その「悪」が少ないため、NULLと同じです。
NULLと空の文字列が同じではない言語では、常に両方の条件を確認する必要があります。
Oracle Databaseは現在、長さがゼロの文字値をNULLとして扱います。ただし、今後のリリースではこれが引き続き当てはまらない可能性があるため、空の文字列をNULLと同様に扱わないことをお薦めします。
考えられる理由
val IS NOT NULL
はval != ''
より読みやすいval != '' and val IS NOT NULL
本からの例
set serveroutput on;
DECLARE
empty_varchar2 VARCHAR2(10) := '';
empty_char CHAR(10) := '';
BEGIN
IF empty_varchar2 IS NULL THEN
DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL');
END IF;
IF '' IS NULL THEN
DBMS_OUTPUT.PUT_LINE(''''' is NULL');
END IF;
IF empty_char IS NULL THEN
DBMS_OUTPUT.PUT_LINE('empty_char is NULL');
ELSIF empty_char IS NOT NULL THEN
DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL');
END IF;
END;