php - 调试 PDO mySql 将 NULL 插入数据库而不是空的

标签 php mysql insert pdo null

我正在尝试使用 PDO 将“NULL”动态插入到数据库中。

表结构:

CREATE TABLE IF NOT EXISTS `Fixes` (
  `Id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'PK',
  `CurrencyId` int(11) NOT NULL COMMENT 'FK',
  `MetalId` int(11) NOT NULL COMMENT 'FK',
  `FixAM` decimal(10,5) NOT NULL,
  `FixPM` decimal(10,5) DEFAULT NULL,
  `TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`Id`),
  KEY `CurrencyId` (`CurrencyId`),
  KEY `MetalId` (`MetalId`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=13 ;

PHP/PDO 查询:

$sql = 'UPDATE 
            Fixes
    SET 
            FixAM = :fixAM,
        FixPM = :fixPM
        WHERE
            MetalId IN (SELECT Id FROM Metals WHERE Name = :metal) AND
        CurrencyId IN (SELECT Id FROM Currencies Where Id = :currency)';

$stmt = $db->prepare($sql); 

for ($i = 0; $i<3; $i++) {  
    $stmt->execute(array(
    ':metal' => 'Silver', 
    ':fixAM' => $fix['FixAM'][$i], 
    ':fixPM' => $fix['FixPM'][$i],
    ':currency' => ($i+1))
    );      
}

例如有时,$fix['FixPM'][$i] 的值有时为“NULL”。我如何将其插入数据库?当我运行查询然后查看数据库中的数据时,这条记录显示 0.0000,而不是 null。

How do I insert NULL values using PDO?提供了一些解决方案。

  • 我认为我不能按照示例使用 $stmt->execute(array( ':v1' => null, ':v2' => ... )) 因为有时项目为空,有时不是。因此,我需要引用我创建的变量 $fix['FixPM'][$i] 并在需要时将其设为 null

提前致谢。

最佳答案

在我看来,这是 PDO 准备语句模拟中的一个(未报告?)错误:

  1. implementation PDOStatement::execute() eventually调用 pdo_parse_params() ;

  2. 反过来,attempts to quote/escape values基于相关参数的数据类型(由 PDOStatement::bindValue()PDOStatement::bindParam()$data_type 参数指示——所有作为 $input_parameters 提供给 PDOStatement::execute() 的参数都被处理如 PDO::PARAM_STR,如该函数的文档中所述);

  3. 字符串类型的值由 calling 转义/引用相关数据库驱动程序的 quoter()方法,不管它们是否为 null:在 PDO_MySQL 的情况下,这是 mysql_handle_quoter() ,它(最终)将值传递给 mysqlnd_cset_escape_quotes()mysql_cset_escape_slashes() ,取决于服务器的 NO_BACKSLASH_ESCAPES SQL模式;

  4. 给定一个 null 参数,这两个函数都返回一个空字符串。

我的意见是,在 switching on the parameter's type 之前(在上面的步骤 2 中),如果值为 nullpdo_parse_params() 应将类型设置为 PDO::PARAM_NULL。但是,有些人可能会争辩说,这会阻止在适当的情况下对 null 值进行特定类型的处理,在这种情况下 string case (在上面的第 3 步中)在继续调用驱动程序的 quoter() 方法之前,绝对应该处理 null 值。

作为临时解决方法,禁用准备好的语句模拟通常是最好的方法:

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);

关于php - 调试 PDO mySql 将 NULL 插入数据库而不是空的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13941568/

相关文章:

php - 在 PHP < 5.4 中,有什么方法可以获取您刚刚设置的状态响应代码?

mysql - 如何使用 case 子句创建 sql 请求

mysql - Sails.js:如何为记录做updatedDate?

Mysql:如何获得给定条件的逆结果?

sql-server - 获取插入行的 PK Guid 的最佳方法

MySQL 插入并确定插入时的值

php - 为什么我的 $_GET 表单不能将数据(使用 PHP)插入到 MySql 数据库或表中?

PHP状态机框架

php - 实现母版页功能。 PHP

php - Composer 更新没有说明要安装或更新