私はそれが ''をと見なしていることを知っていNULL
ますが、これが事実である理由を私に伝えることはあまりありません。SQL仕様を理解しているように、 ''は同じではありませんNULL
-1つは有効なデータムであり、もう1つは同じ情報がないことを示しています。
遠慮なく推測してください。その場合はそれを示してください。Oracleからコメントできる人がいたら、それは素晴らしいことです。
私はそれが ''をと見なしていることを知っていNULL
ますが、これが事実である理由を私に伝えることはあまりありません。SQL仕様を理解しているように、 ''は同じではありませんNULL
-1つは有効なデータムであり、もう1つは同じ情報がないことを示しています。
遠慮なく推測してください。その場合はそれを示してください。Oracleからコメントできる人がいたら、それは素晴らしいことです。
回答:
答えは、Oracleは非常に古いということです。
SQL標準が存在する前の昔、OracleはVARCHAR
/ VARCHAR2
列に空の文字列がNULL
あり、NULLの感覚が1つだけであるという設計上の決定をしました(要求されたことのないデータを区別する関係理論家がいます)。回答はあるがユーザーには分からないデータ、回答がないデータなど、いずれもある程度の感覚を構成しNULL
ます。
SQL標準が登場しNULL
、空の文字列が別個のエンティティであることに同意した時点で、Oracleユーザーは、2つが同等であると想定したコードをすでに持っていました。したがって、Oracleは基本的に、既存のコードを壊す、SQL標準に違反する、または潜在的に多数のクエリの機能を変更するようなある種の初期化パラメーターを導入するという選択肢を残していました。SQL標準(IMHO)への違反は、これらの3つのオプションの中断が最も少ないものでした。
OracleはVARCHAR
、SQL規格に準拠するために将来のリリースでデータ型が変更される可能性を残しています(そのVARCHAR2
ため、そのデータ型の動作は今後も同じであることが保証されているため、誰もがOracleで使用します)。
オラクルのトム・カイト副社長:
長さがゼロのvarcharはNULLとして扱われます。
''はNULLとして扱われません。
''は、char(1)に割り当てられると ''になります(char型は空白が埋め込まれた文字列です)。
'' varchar2(1)に割り当てられた場合、 ''は長さ0の文字列であり、長さ0の文字列はOracleではNULLです(長くはありません '')
''
に暗黙的に変換されるときに最も混乱する状況が発生します。たとえばcast('' as char(1)) is null
以前の開発者がおそらく考えていた方法でOracleをデータエントリシステムの美化されたバックエンドとして考えれば、これはもっと理にかなっていると思います。データベース内のすべてのフィールドは、データ入力オペレーターが画面で見たフォームのフィールドに対応しています。オペレーターがフィールドに何も入力しなかった場合、それが「誕生日」であろうと「住所」であろうと、そのフィールドのデータは「不明」です。オペレーターが誰かのアドレスが実際には空の文字列であることを示す方法はありません。それはとにかくあまり意味がありません。
Oracleのドキュメントでは、少なくともバージョン7までさかのぼって、この問題について開発者に警告しています。
Oracleは、「不可能な値」の手法でNULLSを表すことを選択しました。たとえば、数値の位置にあるNULLは、「マイナスゼロ」、つまり不可能な値として格納されます。計算の結果生じるマイナスのゼロは、格納される前に正のゼロに変換されます。
Oracleはまた、誤って、長さがゼロのVARCHAR文字列(空の文字列)を不可能な値と見なし、NULLを表すための適切な選択を選択しました。空の文字列は不可能な値にはほど遠いことがわかります。文字列の連結のもとでのアイデンティティです!
Oracleのドキュメントは、データベースの設計者と開発者に対して、Oracleの将来のバージョンでは、空の文字列とNULLの間のこの関連付けを解除し、その関連付けに依存するすべてのコードを解除する可能性があることを警告しています。
不可能な値以外にNULLSにフラグを付ける手法はありますが、Oracleはそれらを使用しませんでした。
(上の「場所」という言葉は、行と列の交差を意味するために使用しています。)
空の文字列はNULLと同じです。これは、2つ(空の文字列とnull)が同じではない状況と比較すると、「より小さな悪」だからです。
NULLと空の文字列が同じでない言語では、常に両方の条件をチェックする必要があります。
not null
列に制約を設定し、空の文字列のみをチェックします。
Oracle Databaseは現在、長さがゼロの文字値をNULLとして扱います。ただし、これは今後のリリースでは当てはまらない可能性があるため、空の文字列をnullと同じように処理しないことをお勧めします。
考えられる理由
val IS NOT NULL
より読みやすい val != ''
val != '' and val IS NOT NULL
val <> ''
はすでに除外されていますNULL
。たぶん、あなたが意味したval = '' OR val IS NULL
。ただし、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;
NULLとして扱わないことも、特に役に立ちません。
Oracleのこの領域で間違いを犯した場合、通常はすぐに気づきます。ただし、SQLサーバーでは動作するように見え、問題は誰かがNULLではなく空の文字列を入力した場合にのみ発生します(おそらく.netクライアントライブラリから、nullは ""とは異なりますが、通常は同じように扱います) )。
Oracleが正しいと言っているわけではありませんが、どちらの方法もほぼ同じように悪いように思えます。
確かに、私はOracleに対処するのに何の困難もありませんでした、明らかにいくつかのバグを介してデータベースに挿入することが許可されている無効な日時値(印刷、変換、または何もない、DUMP()関数で見ただけ)を含むバイナリ列としてのクライアントのバージョン!データベースの整合性を保護するためにこれだけです!
OracleのNULLリンクの処理:
http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/
http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html
まず第一に、Oracleはnullとnull文字列を常に同じものとして扱うわけではありませんでした。null文字列は、定義上、文字を含まない文字列です。これはnullとまったく同じではありません。NULLは、定義上、データがないことを意味します。
5年または6年ほど前、Oracleではnull文字列の扱いがnullとは異なりました。nullのように、null文字列はすべてに等しく、すべてとは異なりましたが(nullには問題ないと思いますが、null文字列は完全に間違っています)、少なくともlength(null文字列)は0を返します長さがゼロの文字列。
現在Oracleでは、length(null)はnullを返しますが、これは問題ないと思いますが、length(null string)もnullを返します。これは完全に間違っています。
彼らがこれら2つの異なる「値」を同じように扱い始める理由を理解していません。それらは異なることを意味し、プログラマーはそれぞれに異なる方法で行動する能力を持つ必要があります。彼らが方法論を変更したという事実は、これらの値がどのように扱われるべきかについて彼らが本当に手がかりを持っていないことを私に話します。
NULL
、null の処理にグローバルな変更はまったく導入されておらず、null値の文字列との違いはありませんでした。そのような違いは意味がありません。この答えは完全なファンタジーだと思います。