[.NET][JavaScript][SQL] null と空文字の等価/不等価判定を言語別に並べて比較してみた
言語によって null や空文字の扱いは異なることがあります。
以下に例を示します。(★は注意が必要です)
■Equals
[C#]
Equals(null, null)
true
[VB.NET]
Equals(Nothing, Nothing)
True
■Is
[VB.NET]
(Nothing Is Nothing)
True
[JavaScript]
Object.is(null, null)
true
[SQL(ANSI/ISO 準拠)]
(NULL IS NULL)
TRUE
■Is Not
[VB.NET]
(Nothing IsNot Nothing)
False
[SQL(ANSI/ISO 準拠)]
(NULL IS NOT NULL)
FALSE
■null との等号比較
[C#]
(null == null)
true
[VB.NET]
(Nothing = Nothing)
True
[JavaScript]
(null === null)
true
(null == null)
true
[SQL(ANSI/ISO 準拠)]
★(NULL = NULL)
UNKNOWN
★NOT (@nullString = NULL)
UNKNOWN
※NOT しても UNKNOWN(以下同様)
■null との不等号比較
[C#]
(null != null)
false
[VB.NET]
(Nothing <> Nothing)
False
[JavaScript]
(null !== null)
false
(null != null)
false
[SQL(ANSI/ISO 準拠)]
★(NULL <> NULL)
UNKNOWN
■空文字との等号比較
[C#]
(null == "")
false
[VB.NET]
★(Nothing = "")
True
[JavaScript]
(null === "")
false
(null == "")
false
[SQL(ANSI/ISO 準拠)]
★(NULL = '')
UNKNOWN
■空文字との不等号比較
[C#]
(null != "")
true
[VB.NET]
★(Nothing <> "")
False
[JavaScript]
(null !== "")
true
(null != "")
true
[SQL(ANSI/ISO 準拠)]
★(NULL <> '')
UNKNOWN
■有効文字との等号比較
[C#]
(null == "a")
false
[VB.NET]
(Nothing = "a")
False
[JavaScript]
(null === "a")
false
(null == "a")
false
[SQL(ANSI/ISO 準拠)]
★(NULL = 'a')
UNKNOWN
■有効文字との不等号比較
[C#]
(null != "a")
true
[VB.NET]
(Nothing <> "a")
True
[JavaScript]
(null !== "a")
true
(null != "a")
true
[SQL(ANSI/ISO 準拠)]
★(NULL <> 'a')
UNKNOWN
■未定義値との等号比較
[JavaScript]
(null === undefined)
false
★(null == undefined)
true
■未定義値との不等号比較
[JavaScript]
(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 を正しく比較できないことを認識したうえで設定しないと「不可解な」挙動に頭を抱えることになりかねませんので注意しましょう。
この記事が気に入ったらサポートをしてみませんか?