MySQL provides a null-safe comparison <=>
(spaceship) operator. That specifies an equality comparison that will return TRUE or FALSE, and won't return NULL when either of the operands is NULL.
As a demonstration:
SELECT NULL=NULL
, NULL<=>NULL
, 1=NULL
, 1<=>NULL
, 1=0
, 1<=>0
, 1=1
, 1<=>1
Returns:
NULL=NULL NULL<=>NULL 1=NULL 1<=>NULL 1=0 1<=>0 1=1 1<=>1
--------- ----------- ------ -------- ------ ----- ------ -----
(NULL) 1 (NULL) 0 0 0 1 1
That comparison operation is essentially shorthand. The return from:
a <=> b
Is equivalent to the return from
( a = b OR ( a IS NULL AND b IS NULL ) )
To answer the question you asked, we could write a statement using the NULL-safe comparison <=>
(spaceship) operator, like this:
SELECT `foo`
FROM `bar`
WHERE `a1` <=> :a1
AND `a2` <=> :a2
Or, for a more ANSI standards compliant and portable approach, we could achieve the same result without using that MySQL specific operator, like this:
SELECT `foo`
FROM `bar`
WHERE ( `a1` = :a1 OR ( `a1` IS NULL AND :a1d IS NULL ) )
AND ( `a2` = :a2 OR ( `a2` IS NULL AND :a2d IS NULL ) )
Note that we need to pass in the value of each bind value two times. In the past, PDO has not allowed more than one reference to a bind placeholder. (Not sure if this is still the case in more recent versions of PDO.) The workaround, as demonstrated above, is to use four distinct placeholders in the statement, and supply the same value for :a1
and :a1d
.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…