Oracle 9iが空の文字列をNULLとして処理するのはなぜですか?
質問
「 」を考慮する ことを知っています NULL
として、しかし、それがなぜであるかを教えてくれません。 SQLの仕様を理解しているため、「 」 NULL
とは異なります。1つは有効なデータであり、もう1つは同じ情報が存在しないことを示しています。
自由に推測できますが、そうであるかどうかを示してください。オラクルからコメントできる人がいれば、それは素晴らしいことです!
解決
答えは、Oracleは非常に古いということだと思います。
SQL標準が登場する以前の時代、オラクルは、 VARCHAR
/ VARCHAR2
列の空の文字列は NULL
そして、NULLの感覚が1つしかなかったこと(プロンプトが一度も表示されていないデータ、回答は存在するがユーザーが知らないデータ、回答のないデータなどを区別するリレーショナル理論家がいます) NULL
)の感覚を構成します)。
SQL標準が登場し、 NULL
と空の文字列が別個のエンティティであることに同意するまでに、2つが同等であると想定したコードを持つOracleユーザーがすでに存在していました。そのため、Oracleには基本的に、既存のコードを破る、SQL標準に違反する、または潜在的に多数のクエリの機能を変更する何らかの初期化パラメーターを導入するオプションが残されていました。 SQL標準(IMHO)に違反することは、これら3つのオプションの中で最も破壊的ではありませんでした。
Oracleは、将来のリリースでSQL標準に準拠するために VARCHAR
データ型が変更される可能性を残しました(だから誰もがOracleで VARCHAR2
を使用するので、そのデータ型の動作は今後も同じままであることが保証されています)。
他のヒント
Tom Kyte オラクルの副社長:
ゼロ長の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はそれらを使用しませんでした。
(行と列の交差を意味するために上記の「場所」という単語を使用しています。)
空の文字列は、その「より少ない悪」が単純であるため、NULLと同じです。 2つ(空の文字列とnull)が同じではない状況と比較した場合。
NULLと空の文字列が同じではない言語では、常に両方の条件を確認する必要があります。
Oracle Databaseは現在、長さがゼロの文字値をNULLとして処理しています。ただし、これは今後のリリースでは引き続き当てはまらない可能性があるため、空の文字列をNULLと同様に扱わないことをお薦めします。
考えられる理由
-
val IS NOT NULL
はval!= ''
より読みやすい
- 条件
val!= ''と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;
NULLとして扱わないことも、特に役立つわけではありません。
Oracleのこの分野で間違いを犯した場合、通常すぐに気づきます。ただし、SQLサーバーでは機能しているように見え、誰かがNULLの代わりに空の文字列を入力した場合にのみ問題が発生します(おそらく。同じ)。
Oracleが正しいと言っているわけではありませんが、どちらの方法もほぼ同じように悪いようです。
実際には、無効な日時値(印刷、変換などはできません。DUMP()関数で見ただけです)を含む、許可明らかにバグのあるクライアントのバイナリ列として、データベースに挿入されます!データベースの整合性を保護するためにこれだけです!
NULLリンクのOracle処理:
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はデータが存在しないことです。
5年または6年ほど前、null文字列はOracleによってnullとは異なる方法で処理されました。 nullのように、null文字列はすべてに等しく、すべてのものとは異なります(nullでは問題ないと思いますが、null文字列では完全に間違っています)、少なくともlength(null string)は0を返します長さゼロの文字列。
現在、Oracleでは、length(null)はnullを返しますが、これはO.K.であると推測されますが、length(null string)もnullを返します。これは完全に間違っています。
これら2つの異なる「値」の処理を開始する理由を理解できません。同じ。それらは異なることを意味し、プログラマーはそれぞれに異なる方法で行動する能力を持つべきです。彼らが方法論を変えたという事実は、これらの値がどのように扱われるべきかについての手がかりが本当にないことを教えてくれます。