【问题标题】:Symfony2 DBAL Update method returning 0Symfony2 DBAL 更新方法返回 0
【发布时间】:2017-12-02 23:01:02
【问题描述】:

我得到一个奇怪的结果,在我的 mySQL 数据库中激活/停用站点用户帐户的更新方法 (http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#update) 调用有时未更新并返回 0。代码如下:

$user_id = '198';
$sqlSetStmnt= [ 'activation_code' => NULL, 'active' => 0 ];
$conn = $this->get( 'database_connection' );

try {

  $result = $conn->update( 'users', $sqlSetStmnt,[ 'id' => (int)$user_id ] );

}
catch( Exception $e ) {

  $error = $e->getMessage();
  throw new \Exception( 'update user account data function -- ' .
                        'error: ' . $error . ' - ' .
                        'unable to update your account!' );

} // End of catch( Exception ) block.

if( ( $result === FALSE ) || ( $result !== 1 ) ) {

  throw new \Exception( 'update user account data function -- ' .
                        'update return value: ' . $result . ' - ' .
                        'unable to update your account!' );

} // if( ( $result === FALSE ) || ( $result !== 1 ) ) ...

users 表有一个作为主键的 id int(11) 列,一个 active tinyint(1) 列,以及activation_code varchar(40) NULL 列。

请注意,$user_id 变量包含一个字符串值 '198',但在创建 $sqlSetStmnt 值时它被强制转换为 int。

检查 users 表确认 users 表中有一行 id 列值为 198更新调用。

运行更新调用时使用的帐户有足够的权限来更改行 activeactivation_code 列的值。

系统中没有其他用户或访问数据库,因此该行上没有任何锁。

我使用 x-debug 检查了代码,$user_id$sqlSetStmnt 变量的值已正确设置为我预期的值,即 $resultupdate 方法设置为 0,并且 update 方法调用没有抛出异常。

顺便说一下,没有必要使用变量绑定,因为$user_id$sqlSetStmnt变量中的值不是用户输入的,所以不可能SQL 注入或缓冲区溢出。

有什么方法可以从 DBAL 获取有关 update 方法返回 0 的原因的信息吗?

谢谢。

【问题讨论】:

  • update 返回实际更新的记录数。你是说它实际上是在改变一条记录并返回0?
  • 不,记录似乎没有更新。但是,由于存在具有匹配 id 列值的行,并且 id 列是表的主键,因此我希望应该更新一行并将结果设置为 1 而不是 0。
  • 只有在activation_code 不为空和/或活动值不为零时才会更新该行。基本的 sql 数据库的东西。

标签: mysql symfony sql-update dbal


【解决方案1】:

在解决这个问题之前,我从:

$result = $conn->update( 'users', $sqlSetStmnt, [ 'id' => (int)$user_id ] );

到:

$sqlUpdateStmnt = 'UPDATE `users` SET field = value ' .
                   'WHERE `id` = ' . $user_id;
$result = $conn->executeUpdate( $sqlUpdateStmnt );

并得到完全相同的结果,当用户表中肯定有一行的 id 与 $user_id 的值匹配时,一些更新将返回 0 行。

我通过获取现有行并仅在 set 子句中的字段与表中的相同列不同时才更新该行来解决此问题。

这告诉我返回值 0 并不是没有匹配的行,而是更新后的行对任何行都没有任何影响。

所以这个问题不是错误,而是对结果的误解。但是,在使用update()方法时,问题依然存在,如何判断什么时候更新失败是因为没有匹配的行,什么时候没有做任何更改。

我最终的解决方案以预取为代价解决了这个问题,以验证更新是否会影响一行。在我的情况下,对于多用户数据库应用程序,预取实际上不是问题,因为要更新的行可能在更新尝试进行更改之前已被另一个用户删除。但是,如果两种更新方法都能更清楚地解释这一点,并返回不同的值,那就太好了:0 表示没有受影响的行,FALSE 表示没有找到行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 2013-06-01
    • 2017-06-10
    相关资源
    最近更新 更多