从 mySQL 切换到 mariaDB 时间戳混乱
Switch from mySQL to mariaDB timestamp messup
我已经从 MySQL 切换到 MariaDB,这导致了一些 "minor" 问题。一个人已经困扰我好几个小时了,我找不到解决办法。
我通过从 MySQL 导出数据库并将其导入 MariaDB 来移动我的数据库,一切顺利..
当我的更新查询之一不起作用时,我将其缩小到我的数据库处理程序中的这个函数:
public function updateEquipment($type,$product,$acquisition,$calibration_interval,$equipment_no,$inspection_date,$equipment_id,$active)
{
$stmt = $this->conn->prepare("UPDATE equipment SET type = :type, acquisition = :acquisition, calibration_interval = :calibration_interval, equipment_no = :equipment_no, product = :product, inspection_date = :inspection_date, active = :active WHERE id = :equipment_id");
$stmt->bindParam(":equipment_id", $equipment_id,PDO::PARAM_INT);
$stmt->bindParam(":type", $type,PDO::PARAM_STR);
$stmt->bindParam(":acquisition", $acquisition,PDO::PARAM_STR);
$stmt->bindParam(":calibration_interval", $calibration_interval,PDO::PARAM_STR);
$stmt->bindParam(":equipment_no", $equipment_no,PDO::PARAM_STR);
$stmt->bindParam(":product", $product,PDO::PARAM_STR);
$stmt->bindParam(":inspection_date", $this->formatDateStrToTimeStamp($inspection_date),PDO::PARAM_STR);
$stmt->bindParam(":active", $active,PDO::PARAM_INT);
return $stmt->execute();
}
formatDateStrToTimeStamp 函数:
private function formatDateStrToTimeStamp($inspection_date)
{
$day = substr($inspection_date,0,2);
$month = substr($inspection_date,3,2);
$year = substr($inspection_date,6,4);
return date('Y-m-d H:i:s', strtotime($year."-".$month."-".$day));
}
如您所见,我已经关闭了 inspection_date 与代表我要更新的时间戳的字符串的绑定。我在没有更新我的时间戳的情况下测试了该语句,然后它按预期工作。一旦我添加时间戳(在我的例子中我插入了一个静态时间戳),该行将不会更新并且执行不会 return (它应该 return true 或 false)。
这是我的 table 结构:
CREATE TABLE `equipment` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`type` text NOT NULL,
`acquisition` text NOT NULL,
`calibration_interval` text NOT NULL,
`equipment_no` text NOT NULL,
`product` text NOT NULL,
`inspection_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`active` int(11) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
问题:时间戳在 mariaDB 中的处理方式不同吗,因为自从切换后我没有对我的代码进行任何更改,我只是从我所做的导出中导入了我的数据库来自我的 MySQL 数据库。
调试完后(因为我不太擅长调试 Web 应用程序)我终于找到了问题的答案。
PDO 的 bindparam 必须将变量绑定到占位符或问号,这在 pdo 文档中也有说明。在我的例子中,我尝试在绑定时直接插入一个字符串,并且带有错误的原始代码使用了时间戳格式化程序的 return 值。在这两种情况下,我在绑定到我的占位符时都没有使用变量,因此出现了错误....
我在使用 Chrome 的 Advanced Rest Client 调试函数时遇到了错误,它显示了一个错误:"Only variables should be passed by reference".
解决方案一:
$inspect = $this->formatDateStrToTimeStamp($inspection_date);
$stmt->bindParam(":inspection_date", $inspect,PDO::PARAM_STR);
方案二:
正如 Ryan Vincent 在评论中指出的那样,改用 bindValue(请参阅他的评论以获取更多灵感)
但还是有点糊涂:
不过,我仍然有点困惑,因为之前的代码 运行 在另一台主机上没有问题。我不记得 PHP 版本或任何东西,但如果有人可以确认它在以前的版本中是可能的,它会解释为什么...
我已经从 MySQL 切换到 MariaDB,这导致了一些 "minor" 问题。一个人已经困扰我好几个小时了,我找不到解决办法。
我通过从 MySQL 导出数据库并将其导入 MariaDB 来移动我的数据库,一切顺利..
当我的更新查询之一不起作用时,我将其缩小到我的数据库处理程序中的这个函数:
public function updateEquipment($type,$product,$acquisition,$calibration_interval,$equipment_no,$inspection_date,$equipment_id,$active)
{
$stmt = $this->conn->prepare("UPDATE equipment SET type = :type, acquisition = :acquisition, calibration_interval = :calibration_interval, equipment_no = :equipment_no, product = :product, inspection_date = :inspection_date, active = :active WHERE id = :equipment_id");
$stmt->bindParam(":equipment_id", $equipment_id,PDO::PARAM_INT);
$stmt->bindParam(":type", $type,PDO::PARAM_STR);
$stmt->bindParam(":acquisition", $acquisition,PDO::PARAM_STR);
$stmt->bindParam(":calibration_interval", $calibration_interval,PDO::PARAM_STR);
$stmt->bindParam(":equipment_no", $equipment_no,PDO::PARAM_STR);
$stmt->bindParam(":product", $product,PDO::PARAM_STR);
$stmt->bindParam(":inspection_date", $this->formatDateStrToTimeStamp($inspection_date),PDO::PARAM_STR);
$stmt->bindParam(":active", $active,PDO::PARAM_INT);
return $stmt->execute();
}
formatDateStrToTimeStamp 函数:
private function formatDateStrToTimeStamp($inspection_date)
{
$day = substr($inspection_date,0,2);
$month = substr($inspection_date,3,2);
$year = substr($inspection_date,6,4);
return date('Y-m-d H:i:s', strtotime($year."-".$month."-".$day));
}
如您所见,我已经关闭了 inspection_date 与代表我要更新的时间戳的字符串的绑定。我在没有更新我的时间戳的情况下测试了该语句,然后它按预期工作。一旦我添加时间戳(在我的例子中我插入了一个静态时间戳),该行将不会更新并且执行不会 return (它应该 return true 或 false)。
这是我的 table 结构:
CREATE TABLE `equipment` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`type` text NOT NULL,
`acquisition` text NOT NULL,
`calibration_interval` text NOT NULL,
`equipment_no` text NOT NULL,
`product` text NOT NULL,
`inspection_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`active` int(11) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
问题:时间戳在 mariaDB 中的处理方式不同吗,因为自从切换后我没有对我的代码进行任何更改,我只是从我所做的导出中导入了我的数据库来自我的 MySQL 数据库。
调试完后(因为我不太擅长调试 Web 应用程序)我终于找到了问题的答案。
PDO 的 bindparam 必须将变量绑定到占位符或问号,这在 pdo 文档中也有说明。在我的例子中,我尝试在绑定时直接插入一个字符串,并且带有错误的原始代码使用了时间戳格式化程序的 return 值。在这两种情况下,我在绑定到我的占位符时都没有使用变量,因此出现了错误....
我在使用 Chrome 的 Advanced Rest Client 调试函数时遇到了错误,它显示了一个错误:"Only variables should be passed by reference".
解决方案一:
$inspect = $this->formatDateStrToTimeStamp($inspection_date);
$stmt->bindParam(":inspection_date", $inspect,PDO::PARAM_STR);
方案二:
正如 Ryan Vincent 在评论中指出的那样,改用 bindValue(请参阅他的评论以获取更多灵感)
但还是有点糊涂: 不过,我仍然有点困惑,因为之前的代码 运行 在另一台主机上没有问题。我不记得 PHP 版本或任何东西,但如果有人可以确认它在以前的版本中是可能的,它会解释为什么...