PDO执行mysql cli无法执行的语句

时间:2014-10-22 15:31:03

标签: php mysql pdo

我有一个带有unsigned int的数据库表,表示钱包余额。此列称为钱包。它位于一个名为users的表中。

以下查询通过mysql cli失败:

UPDATE users set wallet = `wallet` - 550000000 WHERE username = 'user'

显示错误消息:

  

ERROR 1690(22003):BIGINT UNSIGNED值超出范围   '(databaseuserswallet - 550000000)'

问题是,当通过PDO使用ERRMODE_EXCEPTION执行时,它会将钱包余额设置为0并继续执行而不会在异常中引发上述错误

SELECT @@ sql_mode在代码和mysql cli中都不返回任何内容。

这是创建数据库句柄并将其返回给查询对象的函数

//This function connects to a database
public function connect($dbname,DBConfig $config = NULL)
{
            //If the connection is already set return it
            if(isset($this->dbs[$dbname]))
               return $this->dbs[$dbname];

            //If the config object is not already set, and still null, throw exception
            if(!isset($this->_config[$dbname]))
            {
               if($config === NULL)
                    throw new PDOdatabasesException('Database configuration object is not set',1);

                $this->_config[$dbname] = $config;
            }

                $config = $this->_config[$dbname];
        //Create a PDO object
        $this->dbs[$dbname] = new PDO(
                            $config::type . 
                            ':host=' . $config::$host . 
                            ';port=' . $config::$port .
                            ';dbname=' . $dbname,
                            $config::$user,
                            $config::$password
                        );

        //Tell the handle to throw exceptions
        $this->dbs[$dbname]->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
        $this->dbs[$dbname]->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );

    //Return a reference to the newly created PDO object
    return $this->dbs[$dbname];
} //End connect()

尝试省去粘贴一堆不必要的代码的需要..我的查询对象从上面获取数据库句柄,并准备并执行此语句:

'UPDATE users SET wallet = wallet - ? WHERE id = ?'

绑定金额(约1000万)和用户ID,然后执行。

电子钱包余额可以为0,查询仍会成功执行。为什么当cli不能发生这种情况?它没有意义!!

我相信我需要再次重申如果将钱包放到0以下,这个查询应该会失败!

它通过pdo成功,但不是通过mysql cli,我的问题是为什么?

2 个答案:

答案 0 :(得分:1)

钱包的结果 - 550000000应小于0且您的列为UNSIGNED。尝试将列类型从BIGINT UNSIGNED更改为BIGINT

答案 1 :(得分:1)

这显然是PDO :: bindValue()和PDO :: bindParam()

中未解决的错误

编辑: 我显然很愚蠢,并没有意识到在将整数绑定到查询时需要定义data_type。

我已将代码简化为以下内容:

$db = new PDO('mysql:dbname=test;host=127.0.0.1','omitted','omitted');

$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

try{
    $statement = $db->prepare("UPDATE test set number = number - ? WHERE id = 1");
    $statement->bindValue(1,1000000000);
    $statement->execute();
}catch(PDOException $e)
{
    die($e->getMessage());
}

将语句更改为(并且不使用bindValue或bindParam):

$statement = $db->prepare("UPDATE test set number = number - 100000000 WHERE id = 1");

然后代码抛出预期的异常

再次改为:     $语句> bindValue(1,1000000000,PDO :: PARAM_INT);

按预期抛出

相关问题