调试PDO mySql在数据库中插入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。

如何使用PDO插入NULL值?提供了一些解决方案。

  • 我不认为我可以使用$stmt->execute(array( ':v1' => null, ':v2' => ... ))作为示例,因为有时项为null,有时则不然。因此,我需要引用我创建的$fix['FixPM'][$i]变量,并在需要时使其为null

提前感谢。

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

  1. PDOStatement::execute()的实现最终调用pdo_parse_params()

  2. 进而尝试根据相关参数的数据类型引用/转义值(如PDOStatement::bindValue()PDOStatement::bindParam()$data_type自变量所示;如该函数的文档中所述,作为$input_parametersPDOStatement::execute()提供的所有参数都被视为PDO::PARAM_STR);

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

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

我的意见是,在打开参数的类型(在上面的步骤2中)之前,如果值为null,则pdo_parse_params()应将类型设置为PDO::PARAM_NULL。然而,有些人可能会争辩说,这将阻止在适当的情况下对null值进行特定类型的处理,在这种情况下,字符串情况(在上面的步骤3中)在继续调用驱动程序的quoter()方法之前,应该明确地处理null值。

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

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

相关内容

  • 没有找到相关文章

最新更新