【问题标题】:MySQL check if null if value is empty using phpMySQL使用php检查是否为空值是否为空
【发布时间】:2021-08-17 16:04:30
【问题描述】:

我有多个类似于下面的数组。

{
  ["sku_original"]=>
  string(33) "98iuoo"
  ["po"]=>
  string(5) "9897"
  ["ca"]=>
  string(3) "557"
  ["cl"]=>
  string(5) "33"
  ["aa"]=>
  string(3) "80"
  ["ad"]=>
  NULL
  ["da"]=>
  string(4) "143.9"
  ["dr"]=>
  NULL
  ["cors"]=>
  NULL
}

我想在数组中的值为空时使用IS NULL 条件,否则我必须检查equal to 条件如果不为空。 我尝试过类似下面的方法。

$po =  $option['po'] != NULL ? $option['po'] : NULL ;
$ca =  $option['ca'] != NULL ? $option['ca'] : NULL ;
$cl =  $option['cl'] != NULL ? $option['cl'] : NULL ;
$aa = $option['aa'] != NULL ? $option['aa'] : NULL ;
$ad = $option['ad'] != NULL ? $option['ad'] : NULL ;
$da = $option['da'] != NULL ? $option['da'] : NULL ;
$dr = $option['dr'] != NULL ? $option['dr'] : NULL ;
$cors = $option['cors'] != NULL ? $option['cors'] : NULL ;

如果选项索引为空,上述代码不会为变量赋值 我也试过 is_null。

和下面的 SQL。

$sql = "SELECT abc FROM `abc` WHERE `po` = $po AND `ca` = $ca AND `cl` = $cl AND `aa` = $aa AND `ad` = $ad AND `da` = $da AND `dr` = $dr AND `dr` = '$dr' AND `cors` = '$cors' `sku` = '$sku' ";

当值为空时,我必须在 SQL 中检查 IS NULL,否则我必须使用 equal to

【问题讨论】:

  • 请分享更多细节。另外,请注意不要使用字符串连接来构建 SQL 查询——它们容易受到 SQL 注入的攻击。更好地使用准备好的语句
  • 我不知道字符串连接 SQL 和准备好的语句。您能否分享任何链接以了解更多信息?
  • 关于预处理语句,如果使用 PDO:php.net/manual/en/pdo.prepared-statements.php,如果使用 MySQLi:php.net/manual/en/mysqli.quickstart.prepared-statements.php
  • 谢谢。我没有额外的细节。我希望我已经解释清楚了
  • 旁注:对于所有这些变量赋值,您可以使用 null coalescing operator 代替:$po = $option['po'] ?? NULL;

标签: php mysql sql arrays null


【解决方案1】:

当您迭代您的选项变量时(假设您已经使用表列名的白名单验证了所有键),有条件地将静态 IS NULL 表达式写入 WHERE 子句或具有非空值的绑定参数.

// unconditionally include sku
$where[] = "sku = ?";
$params = ['s', $sku];
foreach ($option as $key => $value) {
    if ($value === null) {
        $where[] = "$key IS NULL";
    } else {
        $where[] = "$key = ?";
        $params[0] .= 's';
        $params[] = $value;
    }
}

$sql = "SELECT column_with_different_name_from_table
        FROM abc
        WHERE " . implode(" AND " , $where);
$stmt = $conn->prepare($sql);
$stmt->bind_param(...$params);
$stmt->execute();
$result = $stmt->get_result();

foreach ($result as $row) {
    echo $row['column_with_different_name_from_table'] . "<br>";
}

【讨论】:

    【解决方案2】:

    您可以直接在准备好的语句中使用 NULL。这是构建查询的动态方法

    // put all your variables in an array
    $vars = array('po', 'ca', 'ab') ;
    
    // iterate through and set up your key/value pairs
    foreach ($vars as $var) {
      $val = (isset($option[$var]) && !is_null($option[$var])) ? $option[$var] : NULL;
      $q[] = " $var = ? ";
      $v[] = $val ;     
    }
    
    // set up the prepared statement
    $query = "SELECT abc FROM `abc` WHERE " . implode(" AND " , $q) ;
    $stmt = $mysqli->prepare($query);
    $types = str_repeat("s", count($q)) ;
    $stmt->bind_param($types, ...$v);
    $stmt->execute();
    

    【讨论】:

      【解决方案3】:

      如果您只需要可选条件,您可以在 SQL 中通过询问“是参数集,然后使用它,否则不要”来处理这个问题。

      $sql = "SELECT abc FROM abc WHERE (po = $po OR $po IS NULL) AND (ca = $ca OR $ca IS NULL) ...";
      

      也可以写成

      $sql = "SELECT abc FROM abc WHERE po <=> COALESCE($po, po) AND ca <=> COALESCE($ca, ca) ...";
      

      在 MySQL 中(因此每个参数在查询中只使用一次,而不必使用两次)。

      更新:我专注于上述答案中的 SQL。已经提到您不应该通过连接来构建查询字符串,而是使用准备好的语句并绑定变量。这是对的。我不是 PHP 程序员,但似乎上述分配的区别主要是用 : 替换 $。像这样的:

      $sql = "SELECT abc FROM abc WHERE po <=> COALESCE(:po, po) AND ca <=> COALESCE(:ca, ca) ...";
      $query = $pdo->prepare($sql);
      $query->bindParam(":po", $option["po"]);
      $query->bindParam(":ca", $option["ca"]);
      ...
      $query->execute();
      

      【讨论】:

      • 这不符合现代/专业标准。变量不应注入到 sql 字符串中,而应绑定到准备好的语句中的占位符。我没想到会从高级贡献者那里看到这种低质量的建议。这个答案也缺少教育解释。
      • 更重要的是,这些变量注入会导致渲染的 sql 字符串出现语法错误。当您将null 值写入您拥有它们的位置时,sql 只会在其中放置一个长度为零的字符串。
      • @mickmackusa:你当然是对的。我只关注 SQL,但当然不应该通过连接来构建查询字符串,而是使用准备好的语句。 至于我展示的行,这意味着用 : 替换 $。我已经相应地更新了我的答案。感谢您指出这一点。
      • 对于不熟悉 mysql 的 null-safe equals spaceship 运算符的任何人(不要与 php 的三向比较 spaceship 运算符混淆):What is this operator <=> in MySQL?
      • 虽然我很感激您对您的回答进行了现代化改造,但我相信您的回答没有保持所需的逻辑。如果给定的选项值为null,那么它应该只匹配该特定列中存在该空值的行。换句话说,当传入的值为 null 时,您的答案将与 col = col 匹配——这是不对的。我的反馈是否清楚?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 2016-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 2021-05-12
      相关资源
      最近更新 更多