Help us understand the problem. What is going on with this article?

[.NET][JavaScript][SQL] null と空文字の等価/不等価判定を言語別に並べて比較してみた

More than 1 year has passed since last update.

言語によって null や空文字の扱いは異なることがあります。
以下に例を示します。
(赤字は注意が必要な箇所です)

言語ごとの判定結果(C#/VB.NET/JavaScript/SQL)

C# VB.NET JavaScript(厳密/非厳密) SQL(ANSI/ISO 準拠)
Equals Equals(null, null)
true
Equals(Nothing, Nothing)
True
Is (Nothing Is Nothing)
True
Object.is(null, null)
true
(NULL IS NULL)
TRUE
Is Not (Nothing IsNot Nothing)
False
(NULL IS NOT NULL)
FALSE
null との等号比較 (null == null)
true
(Nothing = Nothing)
True
(null === null)
true
(null == null)
true
(NULL = NULL)
UNKNOWN
NOT (NULL = NULL)
UNKNOWN
※NOT しても UNKNOWN(以下同様)
null との不等号比較 (null != null)
false
(Nothing <> Nothing)
False
(null !== null)
false
(null != null)
false
(NULL <> NULL)
UNKNOWN
空文字との等号比較 (null == "")
false
(Nothing = "")
True
(null === "")
false
(null == "")
false
(NULL = '')
UNKNOWN
空文字との不等号比較 (null != "")
true
(Nothing <> "")
False
(null !== "")
true
(null != "")
true
(NULL <> '')
UNKNOWN
有効文字との等号比較 (null == "a")
false
(nullString = "a")
False
(null === "a")
false
(null == "a")
false
(NULL = 'a')
UNKNOWN
有効文字との不等号比較 (null != "a")
true
(Nothing <> "a")
True
(null !== "a")
true
null != "a")
true
(NULL <> 'a')
UNKNOWN
未定義値との等号比較 (null === undefined)
false
(null == undefined)
true
未定義値との不等号比較 (null !== undefined)
true
(null != undefined)
false

ポイントは3つです。

  • VB.NET では、String 型の等価/不等価演算子は Nothing と空文字を等しいと判断します。
  • JavaScript では、非厳密演算子は null と undefined を等しいと判断します。
  • ANSI/ISO 準拠のSQLでは、比較演算子による NULL との比較結果は UNKNOWN となります。(SQL Server で ANSI_NULLS オプションをOFFにすると違う結果になりますが、今後のバージョンでサポートされなくなることがアナウンスされています)

LINQ to Entities における null の扱い

LINQ to Entities の値比較における null の扱いには別途注意が必要です。
Entity Framework 6 で UseDatabaseNullSemantics プロパティ が導入され、既定(false)で (operand1 == operand2) が次のような複雑なSQL式に変換されるようになりました。
※operand1, operand2 がどちらも NULL となりうるケース、たとえば operand1 が NULL 許可列、operand2 が String 型変数の場合を想定します。

(((operand1 = operand2) AND (NOT (operand1 IS NULL OR operand2 IS NULL))) OR ((operand1 IS NULL) AND (operand2 IS NULL)))

どちらかが NULL の場合、ANSI 準拠の等価演算子 '=' では常に UNKNOWN が返されてしまうため、NULL を絡めた比較も正しく行われるような考慮がされています。
設定を true に変えれば (operand1 = operand2) という素直な式が生成されますが、NULL を正しく比較できないことを認識したうえで設定しないと「不可解な」挙動に頭を抱えることになりかねませんので注意しましょう。

CodeOne
【品質と生産性にこだわるシステム開発】 .NET(C#/VB.NET)専門・リモート開発歴10年。即日・1時間から頼める常駐しないエンジニア。確かな技術で開発チームを手堅くサポートします。
https://codeone.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした