定義によると:
SET ANSI_NULLSがONの場合、WHERE column_name = NULLを使用するSELECTステートメントは、column_nameにnull値が含まれていてもゼロ行を返します。 WHERE column_name <> NULLを使用するSELECTステートメントは、column_nameにnull以外の値がある場合でもゼロ行を返します。
これは、このクエリにヌルが含まれないことを意味しますか?
SELECT Region
FROM employees
WHERE Region = @region
または、ANSI_NULL
sはこのようなクエリのみに関係しますか(WHERE
には特定のWord NULL
が含まれます)?
SELECT Region
FROM employees
WHERE Region = NULL
最初の例で@region
がNULL
である場合、Region
がNULL
である行がテーブルにある場合でも、行は返されません。
ANSI_NULLS
がオンの場合(今後オンにしないオプションは今後削除されるため、常にオンに設定する必要があります)、(少なくとも)オペランドの1つがNULL
である比較演算は、3番目の論理値を生成します-UNKNOWN
(TRUE
およびFALSE
とは対照的に)。
UNKNOWN
値は、まだ決定されていない場合(たとえば、AND
オペランドを使用するFALSE
、またはOR
オペランドを使用するTRUE
)、または否定(NOT
)を結合するブール演算子を介して伝搬します。
WHERE
句は、FROM
句によって生成される結果セットをフィルタリングするために使用されます。そのため、行を除外しないためには、WHERE
句の全体の値がTRUE
でなければなりません。そのため、比較によってUNKNOWN
が生成された場合、行が除外されます。
@ user1227804の answer には次の引用が含まれます。
比較の両側が列または複合式である場合、設定は比較に影響しません。
from SET ANSI_NULLS
*
ただし、2つのNULL
列が比較されると(たとえば、JOIN
で)、比較が失敗するため、どのポイントを作成しようとしているのかわかりません。
create table #T1 (
ID int not null,
Val1 varchar(10) null
)
insert into #T1(ID,Val1) select 1,null
create table #T2 (
ID int not null,
Val1 varchar(10) null
)
insert into #T2(ID,Val1) select 1,null
select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and t1.Val1 = t2.Val1
上記のクエリは0行を返しますが、
select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and (t1.Val1 = t2.Val1 or t1.Val1 is null and t2.Val1 is null)
1行を返します。したがって、両方のオペランドが列であっても、NULL
はNULL
と等しくありません。そして、 =
のドキュメント には、オペランドについて何も言うことがありません:
2つの
NULL
式を比較する場合、結果はANSI_NULLS
設定に依存します。
ANSI_NULLS
がON
に設定されている場合、結果はNULL
になります1、NULL
(または不明な)値が別のNULL
または不明な値と等しくないというANSI規則に従います。
ANSI_NULLS
がOFF
に設定されている場合、NULL
をNULL
と比較した結果はTRUE
です。
NULL
をNULL
以外の値と比較すると、常にFALSE
になります2。
ただし、両方 1 そして 2 正しくない-両方の比較の結果はUNKNOWN
です。
*このテキストの不可解な意味は、数年後にようやく発見されました。実際に意味するのは、これらの比較では、設定は効果がなく、設定が常にONであるかのように動作するということです。 SET ANSI_NULLS OFF
が影響を及ぼさない設定であると述べていれば、より明確になっていたでしょう。
@Region
がnull
の値でない場合(@Region = 'South'
と言います)、ANSI_NULLSの値に関係なく、Regionフィールドがnullの行を返しません。
ANSI_NULLSは、@Region
の値がnull
である場合、つまり最初のクエリが本質的に2番目のクエリになる場合にのみ違いを生じます。
その場合、ANSI_NULLS ONは行を返しません(null = null
は不明なブール値(別名null
)を生成するため)、ANSI_NULLS OFFはRegionフィールドがnullである行を返します(null = null
はtrue
を生成します)
ANSI_NULLSをオンに設定
ITは、テーブル内のnull値を含むすべての値を返します
ANSI_NULLSをオフに設定
列にヌル値が含まれる場合に終了します
https://docs.Microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql
SET ANSI_NULLSがONの場合、WHERE column_name = NULLを使用するSELECTステートメントは、column_nameにnull値が含まれていてもゼロ行を返します。 WHERE column_name <> NULLを使用するSELECTステートメントは、column_nameにnull以外の値がある場合でもゼロ行を返します。
例えば
DECLARE @TempVariable VARCHAR(10)
SET @TempVariable = NULL
SET ANSI_NULLS ON
SELECT 'NO ROWS IF SET ANSI_NULLS ON' where @TempVariable = NULL
-- IF ANSI_NULLS ON , RETURNS ZERO ROWS
SET ANSI_NULLS OFF
SELECT 'THERE WILL BE A ROW IF ANSI_NULLS OFF' where @TempVariable =NULL
-- IF ANSI_NULLS OFF , THERE WILL BE ROW !
ANSI NULLSをオフに設定すると、NULL = NULL比較がtrueを返します。 EG:
SET ANSI_NULLS OFF
select * from sys.tables
where principal_id = Null
以下に示すような結果が返されます。zcwInvoiceDeliveryType 744547 NULL zcExpenseRptStatusTrack 2099048 NULL ZCVendorPermissions 2840564 NULL ZCWOrgLevelClientFee 4322525 NULL
このクエリは結果を返しませんが:
SET ANSI_NULLS ON
select * from sys.tables
where principal_id = Null