【问题标题】:INSERTing value '000' with PDO results in NULL使用 PDO 插入值“000”导致 NULL
【发布时间】:2018-05-29 21:24:16
【问题描述】:

在处理整数值 0 时,让 PDO 像我需要的那样工作时遇到了一点麻烦。

在模拟订单系统中,final_status0 代表成功下单。顺序错误会导致 final_status 的非零整数,例如 14、5 等。不完整的订单需要一个实际的 NULL final_status

这是示例表结构:

CREATE TABLE `order_status` (
  `order_id` int(10) NOT NULL,
  `final_status` int(10) DEFAULT NULL,
  `date_status` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

更新订单时,我遇到了一个问题,即 PDO 将 0 的 final_status 设置为 NULL,或者将实际的 NULL/空白值设置为 0(取决于我在绑定语句中声明的常量) .

所以,假设:

$final_status = 0000;
$order_id = 123456;

更新查询:

try
{
    $q = "
        UPDATE
            order_status 
        SET
            final_status = :final_status
        WHERE
            order_id = :order_id 
    ";
    $stmt = $dbx_pdo->prepare($q);
    $stmt->bindValue(':final_status',       !empty($final_status)       ? $final_status     : NULL, PDO::PARAM_NULL);   
    $stmt->bindValue(':order_id',           !empty($order_id)           ? $order_id         : NULL, PDO::PARAM_INT);
    $stmt->execute();
    $stmt->closeCursor();

} catch(PDOException $err) {
    error_handler();
}   

如果我将 PARAM_NULL 用于第一个 bindParam 常量,则“0000”值或空白值将转换为 NULL,这会产生假阴性。

如果我使用 PARAM_INT,'0000' 值或空白值将被转换为 0,这会产生误报并且很糟糕。

那么,表定义是罪魁祸首,还是有办法用 INT 做我想做的事?

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    我认为(不确定),问题在于您使用的是!empty()。这会将0 转换为false,这将使三元条件无效。因此如果$final_status == 0,你的三元条件将返回null。

    尝试将其更改为:

    isset($final_status) && $final_status >= 0 ? $final_status : null
    

    is_null($final_status) ? null : (int) $final_status
    

    如果这个答案不起作用,请发表评论,我会删除它以避免将来混淆。

    【讨论】:

    • 明天下午测试并跟进。
    • 这是最终成功的 bindValue 行。它正确处理 0、整数和空白值的 final_status 值。 $stmt->bindValue(':final_status', isset($final_status) ? $final_status : NULL, PDO::PARAM_INT);
    【解决方案2】:

    来自官方文档http://php.net/manual/en/function.empty.php 以下值被认为是空的:

    • “”(空字符串)
    • 0(0为整数)
    • 0.0(0 作为浮点数)
    • “0”(0作为字符串)
    • 错误
    • array()(一个空数组)

    这将返回 true。

    <?php
        $final_status = 000;
        echo empty($final_status);
    

    考虑改用 isset。

    $stmt->bindValue(':final_status',       !isset($final_status)       ? $final_status     : NULL, PDO::PARAM_NULL);
    

    【讨论】:

    • 这是最终成功的 bindValue 行。它正确处理 0、整数和空白值的 final_status 值。 $stmt-&gt;bindValue(':final_status', isset($final_status) ? $final_status : NULL, PDO::PARAM_INT);
    猜你喜欢
    • 2021-07-28
    • 2016-02-25
    • 2017-05-06
    • 1970-01-01
    • 2016-05-16
    • 2019-07-06
    • 2015-01-28
    • 2017-12-27
    • 2013-11-21
    相关资源
    最近更新 更多