【问题标题】:2147483647 getting inserted into DB field even though the datatype is VARCHAR2147483647 即使数据类型是 VARCHAR 也被插入到 DB 字段中
【发布时间】:2014-05-15 10:47:35
【问题描述】:

这是我们近一周来一直在努力解决的问题。

发生了什么?

  • 在我们的应用程序中,我们有一个电话号码字段,它与数据类型为 VARCHAR(25) 的数据库字段相关。我们使用 INT、BIGINT。

  • 在提交表单时,我们将数据存储如下。

    1. $_POST

    2. 使用filter_input(INPUT_POST, 'mobile', FILTER_SANITIZE_STRING);清理数据

    3. 使用mysqli->prepare 将数据插入数据库,其中绑定参数也已正确设置。该字段设置为使用“s”(字符串)进行映射。

    4. 然后将数据存储到数据库中。

  • 现在我们在调试问题时将所有这些值记录在单独的日志文件中。最奇怪的是在查看日志文件时发现了这一点。似乎通过 POST 发送的数据正确到达,经过消毒后仍然很好,插入数据库后立即检索数据仍然很好。但是当我们的前端应用程序获取相同的值显示给用户端时,获取的数据是 2147483647。

  • 所有此类插入都不会发生此问题,它非常随机且很少发生,但已将我们带到了一个点,我正在努力寻找解决方案。

  • 开发平台信息:PHP 5.3、MySQL 5.5.31

任何帮助将不胜感激。

代码

代码如下:

$Mobile = filter_input(INPUT_POST, 'mobile', FILTER_SANITIZE_STRING);

$stmt = $mysqli->prepare("INSERT INTO enquiry(idAdminUsers, isConverted, Firstname, Lastname , Residence , WorkCollege , Gender , Age , Occupation , Mobile , Email , Transport , FirstMile , LastMile , Commute , NoPublicTransport , Member , YesMember , PurposeMember , NoMember , Note, Date, FirstMileCost, FirstMileTime, LastMileCost, LastMileTime, landlineNumber) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),?,?,?,?,?)");
    if ($stmt) {
        if ($stmt->bind_param('iisssssissssssssisssssssss', $idAdminUsers, $isConverted, $firstName, $lastName, $Residence, $WorkCollege, $Gender, $Age, $Occupation, $Mobile, $Email, $Transport, $FirstMile, $LastMile, $Commute, $NoPublicTransport, $Member, $YesMember, $PurposeMember, $NoMember, $Note, $FirstMileCost, $FirstMileTime, $LastMileCost, $LastMileTime, $landlineNumber)) {
$stmt->execute()' 

一旦插入,就会按照以下方式进行检索

$stmt = $mysqli->prepare("SELECT idEnquiry , idAdminUsers , isConverted , Firstname , Lastname , Residence , WorkCollege , Gender , Age , Occupation , Mobile , Email , Transport , FirstMile , LastMile , Commute , NoPublicTransport , Member , YesMember , PurposeMember , NoMember , Note, Date, FirstMileCost, FirstMileTime, LastMileCost, LastMileTime, landlineNumber FROM enquiry WHERE idEnquiry = ?");
    if ($stmt) {
        if ($stmt->bind_param('i', $idEnquirySelect)) {
            if ($stmt->execute()) {

这正在被记录,并表明数据已正确输入。但是一旦我们去检查数据库,非常随机的数据是不正确的。

以下是数据库建表脚本:

CREATE TABLE IF NOT EXISTS `enquiry` (
  `idEnquiry` int(11) NOT NULL AUTO_INCREMENT,
  `Firstname` varchar(255) DEFAULT NULL,
  `Mobile` varchar(25) DEFAULT NULL,
  `Email` varchar(45) DEFAULT NULL,
  `Age` int(16) DEFAULT NULL,
  `idAdminUsers` int(11) DEFAULT NULL,
  `Member` tinyint(4) DEFAULT NULL,
  `isConverted` tinyint(4) DEFAULT NULL,
  `Note` text,
  `Residence` varchar(255) DEFAULT NULL,
  `WorkCollege` varchar(255) DEFAULT NULL,
  `Transport` varchar(31) DEFAULT NULL,
  `FirstMile` varchar(31) DEFAULT NULL,
  `LastMIle` varchar(31) DEFAULT NULL,
  `Gender` varchar(8) DEFAULT NULL,
  `Commute` text,
  `NoPublicTransport` varchar(64) DEFAULT NULL,
  `YesMember` varchar(255) DEFAULT NULL,
  `PurposeMember` varchar(128) DEFAULT NULL,
  `NoMember` varchar(128) DEFAULT NULL,
  `Occupation` varchar(64) DEFAULT NULL,
  `Lastname` varchar(255) DEFAULT NULL,
  `Date` date DEFAULT NULL,
  `FirstMileCost` varchar(45) DEFAULT NULL,
  `FirstMileTime` varchar(45) DEFAULT NULL,
  `LastMileCost` varchar(45) DEFAULT NULL,
  `LastMileTime` varchar(45) DEFAULT NULL,
  `landlineNumber` varchar(15) NOT NULL,
  PRIMARY KEY (`idEnquiry`),
  UNIQUE KEY `idenquiry_UNIQUE` (`idEnquiry`),
  UNIQUE KEY `Email_UNIQUE` (`Email`),
  KEY `idAdminUserFK_idx` (`idAdminUsers`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='All the enquiry details are added to this table.' AUTO_INCREMENT=482 ;

【问题讨论】:

  • 您的数据库中是否显示正确的数据?你能告诉我们有问题的前端应用程序的代码吗?
  • 您能否确认数据库中存储的值确实是2147483647(直接查询数据库,而不是通过您的前端应用程序?)
  • 什么数据变成了2147483647?
  • 你希望这个值如何输出?
  • @parthk 我在您的代码中看到您如何检索插入的数据。但是您没有向我们展示您如何回应您所说的看起来正确的值。请显示该代码。另外,如果你说它看起来正确,那么这意味着数据在数据库中是正确的......并且请向我们展示显示错误数据的代码......你如何得到它以及你如何回应它? ...我们需要排除您是否回显错误,或者正确的数据稍后是否被另一个查询覆盖。

标签: php mysql mysqli varchar


【解决方案1】:

分析

这里有两条主要线索。

第一条线索:2147483647

我们对 2147483647 了解多少?

来自维基百科 (http://en.wikipedia.org/wiki/2147483647):

数字 2,147,483,647 也是计算中 32 位有符号整数的最大值。因此,它是在流行计算机上运行的许多编程语言中声明为 int 的变量的最大值。

我们怎样才能得到这个数据库创建的数字?

在几个方面,都与 INT 有关,但由于您的“Mobile”字段数据类型是 VARCHAR 而不是 INT,正如您明确强调的那样,我们知道问题不在于数据库本身。如果该字段是 INT,我们可以继续探索数据库本身以寻找可能的问题。所以我们消除了这种可能性。这给我们留下了可能的代码问题。

第二条线索:日志

这正在被记录,并表明数据已正确输入。但是,一旦我们去检查数据库,非常随机的数据是不正确的。

每次在插入并记录后第一次运行选择查询时 - 它显示(在日志中)输入的数据是正确的,然后当您检查数据库时 - 有时它是正确的,有时它是2147483647.

(通常的)嫌疑人

基于此信息,可以安全地假设 PHP 正在某处将字符串转换为整数,然后在已正确插入该值后将其放入/更新到数据库中。

调试

有几种很好的调试方法:

1) 搜索是否有另一个 UPDATE query 将数据输入到移动字段并覆盖插入的正确数据。对您的所有文件进行完整的代码搜索以查找“移动”一词可能是一个好的开始。

2) 在您的代码中搜索任何出现的intval,因为此函数(或其他类似的函数/方法)可以将字符串转换为 2147483647:Converting a String to an Integer returns 2147483647

3) 在您的 MySQL 数据库中搜索任何其他出现的 2147483647,以确定这是否是一个孤立的问题,或者是否有其他任何东西获得此值,并可能通过某些查询或其他方法将此值复制到 Mobile 字段。

希望这会有所帮助。

【讨论】:

  • 谢谢 Mikey,这确实有帮助。这是一个更新查询,用于标记 Inquiry 转换为实际注册,在其中,prepare 语句由“i”(整数)而不是“s”映射。通过进行全面搜索,这一点被发现。再次感谢!
  • 很高兴它有帮助。这是一个有趣的问题。 ;-)
【解决方案2】:

...插入后立即检索时仍然很好 数据库。 但是当我们的前端获取相同的值时 应用程序显示给用户端,获取的数据是 2147483647.

难道显示的数据是2147483647,而不是获取的数据

因为如果是后者,那么这意味着某些东西正在改变您的数据库中的数据,您需要检查后端和/或属性修改表单(如果有)。

如果是前者,正如我被引导相信的那样,那么可能是一种非常具体且罕见的手机号码格式(可能包含空格?+ 前缀?破折号?其他?)被错误传递,可能是部分传递(例如未加前缀的部分)到intval() 或类似函数,进行格式化以供显示。

验证“错误”数字之一是否仍然完好无损地保存在数据库中;如果是,只需按照控制器和查看路径,数字将显示为 2147483647。

【讨论】:

    猜你喜欢
    • 2021-07-23
    • 2018-08-23
    • 2016-11-19
    • 2018-11-19
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 2019-06-20
    相关资源
    最近更新 更多