提问者:小点点

MySQL PDO与链式SQL一起失败; SQLSTATE[HY000]:常规错误


数据库类型:MariaDB
表引擎:InnoDB

我有一个表,里面有一列的值正在递增(不是自动的,在这个表中没有插入)

当我在phpMyAdmin中运行以下SQL查询时,它可以正常工作:

UPDATE `my_table` 
    SET `my_column` = LAST_INSERT_ID(`my_column` + 1) 
WHERE `my_column2` = 'abc'; 
SELECT LAST_INSERT_ID();

上面的结果为我返回了查询发生时my_column表的最后一个值。 这个查询直接取自mysql关于锁定的文档:https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html(至底部),当您不希望计数器受到其他连接的影响时,这似乎是使用计数器的推荐方式。

我的PDO:

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            
    $sql = "UPDATE `my_table` 
                SET `my_column` = LAST_INSERT_ID(`my_column` + 1) 
                WHERE `my_column2` = 'abc'; 
            SELECT LAST_INSERT_ID();";

    // Prepare statement
    $stmt = $conn->prepare($sql);

    // execute the query
    $stmt->execute();

    $result = $stmt->fetchColumn(); // causes general error
    $result = $stmt->fetch(PDO::FETCH_ASSOC);// causes general error

    // echo a message to say the UPDATE succeeded
    echo $stmt->rowCount() . " records UPDATED successfully";
        
} catch(PDOException $e) {            
    echo $sql . "<br>" . $e->getMessage();        
}
$conn = null;

确切错误SQLSTATE[HY000]:常规错误,如果我移除尝试获取结果的行,它会更新列,但仍然没有返回结果。。。 我如何像在phpMyAdmin中运行时那样一次性地执行更新查询并获得选择结果? 所有这些都需要按照MySQL文档的规定一次性完成,所以我不会遇到两个连接可能获得相同计数器的问题。


共1个答案

匿名用户

不需要执行select LAST_INSERT_ID();。 PDO将自动为您保存该值,您可以将其从PDO中取出。

只需执行以下操作:

$conn = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8mb4", $username, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
        
$sql = "UPDATE `my_table` 
            SET `my_column` = LAST_INSERT_ID(`my_column` + 1) 
            WHERE `my_column2` = 'abc'";

// Prepare statement
$stmt = $conn->prepare($sql);

// execute the query
$stmt->execute();

$newID = $conn->lastInsertId();

LastInsertId()将为您提供上次生成的ID。