简体   繁体   English

用PDO插入值'000'将导致NULL

[英]INSERTing value '000' with PDO results in NULL

I'm having a little trouble getting PDO to work like I need it to work when handling integer value 0. 我在使PDO正常工作时遇到了一些麻烦,就像在处理整数值0时需要它一样。

In a mock order system, final_status 0 represents a successfully placed order. 在模拟订单系统中, final_status 0表示成功下达的订单。 Errors with the order result in a non-zero integer for final_status , such as 14, 5, ect. 该顺序的错误导致final_status的非零整数,例如final_status等。 Incomplete orders need an actual NULL final_status value 不完整的订单需要实际的final_status值为NULL

Here's the example table structure: 这是表格结构示例:

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;

When an order is updated, I'm running into an issue where PDO either sets the final_status of 0 to NULL, or sets actual NULL/blank values to 0 (depending on which constant I declare in the bind statement). 更新订单时,我遇到了一个问题,PDO要么将final_status的0设置为NULL,要么将实际的NULL /空白值设置为0(取决于我在bind语句中声明的常量)。

So, assuming: 因此,假设:

$final_status = 0000;
$order_id = 123456;

The update query: 更新查询:

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();
}   

If I use PARAM_NULL for the first bindParam constant, values of '0000' or blank values are translated to NULL, which creates a false negative. 如果我对第一个bindParam常量使用PARAM_NULL,则将'0000'或空白值转换为NULL,这将创建一个假负数。

If I use PARAM_INT, values of '0000' or blank values are translated to 0, which creates a false positive and is bad. 如果我使用PARAM_INT,则值'0000'或空白值会转换为0,这会导致误报并且是错误的。

So, is the table definition culprit, or is there a way to do what I want with INT? 那么,是表定义的罪魁祸首,还是有一种方法可以用INT做我想做的事情?

I think (not sure), the problem is because you're using !empty() . 我认为(不确定),问题是因为您使用的是!empty() This will convert 0 to false, which will invalidate the ternary condition. 这会将0转换为false,这将使三元条件无效。 Therefore if $final_status == 0 , your ternary condition will return null. 因此,如果$final_status == 0 ,则您的三元条件将返回null。

Try changing it to: 尝试将其更改为:

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

or 要么

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

If this answer doesn't work, comment and I'll delete it to avoid future confusion. 如果此答案不起作用,请发表评论,我将其删除以避免将来造成混淆。

from the official documentation http://php.net/manual/en/function.empty.php The following values are considered to be empty: 摘自官方文档http://php.net/manual/zh/function.empty.php以下值被认为是空的:

  • "" (an empty string) “”(空字符串)
  • 0 (0 as an integer) 0(0为整数)
  • 0.0 (0 as a float) 0.0(0为浮点数)
  • "0" (0 as a string) “ 0”(0作为字符串)
  • NULL 空值
  • FALSE
  • array() (an empty array) array()(一个空数组)

This will return true. 这将返回true。

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

Consider using isset instead. 考虑改用isset。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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