Php 使用COALESCE,但仍会更新列

Php 使用COALESCE,但仍会更新列,php,mysql,pdo,coalesce,Php,Mysql,Pdo,Coalesce,目标是,如果$\u POST['password']为空,则不更新密码列,但它是空的 try { $stmt = $db->prepare('UPDATE users SET email = :email, password = COALESCE(NULLIF(:password, ""), password) WHERE user_id = :user_id'); $stmt->bindValue(':user_id', (int) $_POST['

目标是,如果
$\u POST['password']
为空,则不更新密码列,但它是空的

try {
        $stmt = $db->prepare('UPDATE users SET email = :email, password = COALESCE(NULLIF(:password, ""), password) WHERE user_id = :user_id');
        $stmt->bindValue(':user_id', (int) $_POST['user_id'], PDO::PARAM_INT);
        $stmt->bindValue(':email', $_POST['email'], PDO::PARAM_STR);
        $stmt->bindValue(':password', password_hash($_POST['password'], PASSWORD_BCRYPT), PDO::PARAM_STR);
        $stmt->execute();
        $_SESSION['success'] = 'User updated successfully.';
        header('Location: '.DIRADMIN.'user.php');
        exit;
    } catch(PDOException $e) {
        $_SESSION['error'] = 'An error occurred while updating the user.';
        error_log($e->getMessage(), 0);
    }
有什么想法吗

编辑:
在我的示例中,我使用
COALESCE
返回第一个非空字符串。因此,如果
NULLIF
返回NULL,因为:password等于“”,那么第一个非NULL字符串应该是列password的值。

我个人不会将这种检查委托给您的数据库代码;相反,我可能会在写入数据库之前使用php;这样可以避免建立不必要的数据库连接

例如:

if (isset($_POST['password']) && !empty($_POST['password'])) {
    // write to the database
} else {
    // some error logic to flash the error back to the user
}

问题是您正在将
:password
绑定到
password\u hash
的结果。散列空密码时,结果不是空字符串。尝试:

$stmt->bindValue(':password', 
                 empty($_POST['password']) ? '' : password_hash($_POST['password'], PASSWORD_BCRYPT), 
                 PDO::PARAM_STR);

数据库连接始终是必要的,但并非所有列都必须更新(例如,密码列)。啊,我明白了,所以当用户更新其现有配置文件时,这是有意义的。在这种情况下,我仍然会在php中检查
$\u POST['password']
中是否有任何内容,然后将
password
保留在
SET
语句中,如果它是空的。在这个位
COALESCE(NULLIF(:password,”),password)
中,我认为您打算使用第二个
password
来表示原始密码,但我认为您不能通过列标题引用
SET
语句中的原始值。但我可能错了。@d0ug7a5您肯定可以在
SET
语句中引用原始值。例如,如果要增加一列,可以使用
SET col=col+1
。这是很常见的。问题是,即使密码为空,您也会调用
密码\u hash
。哈希密码不会是空字符串。感谢您提醒我注意这个问题,并为三值运算符+1。