带有'now()+ INTERVAL'的INSERT语句在PDO中插入带有命名占位符的000

时间:2013-01-29 16:44:26

标签: php mysql datetime insert pdo

我无法将此now() + INTERVAL INSERT语句转换为带有命名占位符的PDO预处理语句。

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

这就是我以前使用的:

$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帖子(包括此link建议将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(); 

2 个答案:

答案 0 :(得分:2)

:now()前面有一个冒号 而已。只是一个错字。

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

答案 1 :(得分: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)执行该预准备语句的单个实例,用您使用bindParambindValue绑定的值替换占位符,或将其作为参数传递给{{1} }。

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

现在出现的部分解释了为什么你无法execute()

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

绑定bindValue(":expiry_date", "now() + INTERVAL 3 DAY")时,实际上是绑定了一个字符串。由于它是一个字符串,因此不会以SQL代码的形式执行。