1

我无法将此now() + INTERVALINSERT 语句转换为带有命名占位符的 PDO 准备语句。

当我使用'now() + INTERVAL 3 DAY'or绑定值时'DATE_ADD(now(), INTERVAL 3 DAY)',它会插入 000 而不是正确的日期时间(0000-00-00 00:00:00)

这是我以前使用的:

$qry = "INSERT INTO password_reset(user_id, temp_password, expiry_date) 
VALUES('$member_user_id','$temp_password', now() + INTERVAL 3 DAY)";

新的 PDO 声明:

$stmt = $conn->prepare('INSERT INTO password_reset (user_id, temp_password, expiry_date) 
VALUES(:user_id, :temp_password, :expiry_date)');          
$stmt->bindValue(':user_id', $member_user_id); 
$stmt->bindValue(':temp_password', $random_password); 
$stmt->bindValue(':expiry_date', 'now() + INTERVAL 3 DAY');  
$insertResult = $stmt->execute();                

我也试过这个:

$stmt->bindValue(':expiry_date', 'DATE_ADD(now(), INTERVAL 3 DAY)'); 

几个 SO 帖子中提出的替代方法

一些 SO 帖子(包括此链接建议将 now() 语句放在 VALUES 中而不是绑定它,但这会导致错误消息“无效的参数号:绑定变量的数量与标记的数量不匹配”

$stmt = $conn->prepare('INSERT INTO password_reset (user_id, temp_password, expiry_date) 
VALUES(:user_id, :temp_password, :now() + INTERVAL 3 DAY)');
$stmt->bindValue(':user_id', $member_user_id); 
$stmt->bindValue(':temp_password', $random_password); 
$insertResult = $stmt->execute(); 
4

2 回答 2

2

你前面有一个冒号,:now()
就是这样。只是一个错字。

您的第二条错误消息清楚地表明您实际上并没有删除冒号,而是删除了其他内容 - 很可能是引号。你需要更加注意写作。并更加注意错误消息,它们非常有用。

于 2013-01-29T16:49:39.143 回答
2

从 中删除冒号:now() + INTERVAL 3 DAY

$stmt = $conn->prepare('INSERT INTO password_reset (user_id, temp_password, expiry_date) 
VALUES(:user_id, :temp_password, now() + INTERVAL 3 DAY)');
$stmt->bindValue(':user_id', $member_user_id); 
$stmt->bindValue(':temp_password', $random_password); 
$insertResult = $stmt->execute(); 

或者,您可以这样做:

$stmt = $conn->prepare('
    INSERT INTO
        password_reset (user_id, temp_password, expiry_date) 
    VALUES
        (:user_id, :temp_password, now() + INTERVAL 3 DAY)
');
$insertResult = $stmt->execute(array(
    ":user_id" => $member_user_id,
    ":temp_password" => $random_password)
);

使用准备好的语句时,您应该将语句视为插入数据的模板。

如果您有一个具有以下结构的数据库表:

user_id           INT
temp_password     VARCHAR(128)
expiry_date       DATE

您的表中有三列插入这些列的两个值将来自 PHP另一个将由 SQL 求值。由于 SQL 将在 expiry_date 列上完成所有工作,因此它不需要绑定到 PHP 中的任何内容。

因此,检查INSERT语句:

INSERT INTO password_reset (user_id, temp_password, expiry_date) VALUES (:user_id, :temp_password, now() + INTERVAL 3 DAY)

子句的每个参数都VALUES()需要与子句中声明的列名匹配INSERT INTO table (columns...)

在准备好的语句中,由于我们正在创建一个模板,我们使用它placeholders来显示我们将在语句执行时将值插入到语句的位置。占位符可以是:name您使用过的版本,也可以只是一个问号?

PDO::prepare($statement)告诉 SQL 服务器准备语句。此时,SQL 拥有您的查询模板,并准备好接收该查询中占位符的值。

PDOStatement::execute($placeholderValues)执行该准备好的语句的单个实例,用您绑定的值替换占位符bindParam,bindValue或作为参数传递给execute().

因此,基本上,发送到每个 SQL 服务器的所有内容execute()都是插入占位符的值,而不是整个查询字符串。

现在是解释为什么你不能这样做的部分bindValue(":expiry_date", "now() + INTERVAL 3 DAY")

当值到达 SQL 服务器时,SQL 服务器会清理它们并用它们的值替换相应的占位符。

当您绑定时"now() + INTERVAL 3 DAY",您实际上是在绑定一个字符串。由于它是一个字符串,它不会作为 SQL 代码执行。

于 2013-01-29T16:51:47.773 回答