简体   繁体   中英

pass NULL to php mysql where clause

One of the column in table has been set as NULL , will contain or won't contain value. Now, if user input is NULL then select all row that contains null . If in case of non-empty input, then select accordingly.

WHERE student.section = NULL // tried like '', 'NULL'

But I found this is not a valid way

So I do following logic, but I thought it is not well-structured, I thought it can be shorten, to prevent repetitive code.

if section is null

if(empty($_POST['section'])){
    $result=$con->prepare(
        "SELECT
        ...
        FROM student
        WHERE student.class=:cid AND student.section IS NULL"
    )
    $result->bindParam(':cid',$_POST['class']);
    $result->execute();
} else {
    $result=$con->prepare(
        "SELECT
        ...
        FROM student
        WHERE student.class=:cid AND student.section=:sid"
    )
    $result->bindParam(':cid',$_POST['class']);
    $result->bindParam(':sid',$_POST['section']);
    $result->execute();
}

Remove the superficial table usage. If there are no joins you don't need to put it in again, this will make it "shorter" but keep the same logic.

SELECT
    ...
    FROM student
    WHERE class=:cid AND section=:sid

There I saved you about 14 keystrokes and 0<14 so it's "reduced".

I know I said IS NOT NULL in the comments but logically there is a difference between

  AND student.section=:sid

AND

  AND student.section IS NOT NULL

IF student.section = 10 and :sid is 20, you won't get the record, but if you change it to IS NOT NULL then you will because 10 certainly is not null, but it's also not 20, and thus the logic has been changed. In once case you don't get a record in the other you do.

UPDATE

This is the only other thing I can think of

$sql = 'SELECT
    ...
    FROM student
    WHERE class=:cid AND section';

if(empty($_POST['section']))
    $sql .= ' IS NULL';
else
    $sql .= ' = :sid';

$result=$con->prepare($sql);
$result->bindParam(':cid',$_POST['class']); //this is wrong
$result->execute();

UPDATE1

But, you really shouldn't do this either.

$result=$con->prepare($sql); //this is PDOStatment not a result
$result->bindParam(':cid',$_POST['class']); //this is wrong
$result->execute(); //your not setting a result variable

Also it will be hard to conditionally bind to stmt (PDOStatment object) because you don't yet have it when the query is being constructed. You could do prepare 2x and bind to cid 2x. You could do the condition 2x, and then bind in the second condition. But, we are shorting it and fortunately we can pass the arguments in as an array for execute .

So I would change that to use an array of parameters

$sql = 'SELECT
    ...
    FROM student
    WHERE class=:cid AND section';

$param = [':cid' => $_POST['class']];

if(empty($_POST['section'])){
    $sql .= ' IS NULL';
}else{
    $sql .= ' = :sid';
    $param[':sid'] = $_POST['section'];
}

$stmt=$con->prepare($sql);
$result = $stmt->execute($param);

$data = $result->fetchAll(PDO::FETCH_ALL);

The way you worded the question made it difficult to understand. This is just basically DRY (Don't Repeat Yourself) principles which is good. Unlike WET (Write Everything Twice) ... lol. So when someone says your coding is all WET you know what they mean now. :)

In fact I was so confused I almost missed the $result issue.

Cheers!

When selecting NULL values you shouldn't use equal statements. You should use IS statements, like so:

For null values

SELECT foo
FROM bar
WHERE status IS NULL;

or for not null values

SELECT foo
FROM bar 
WHERE status IS NOT NULL;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM