2016-08-23 2 views
0

Я пытаюсь создать сценарий подтверждения электронной почты.Как исправить ошибку SQLSTATE [42000]; используя подготовленные заявления

Вот мой PHP код:

... 
$q = $dbh->prepare("INSERT INTO `email_confirm` (UserID,token,tokenDate) VALUES(:id, :token, UTC_TIMESTAMP()) ON DUPLICATE KEY UPDATE token = VALUES(:token), tokenDate = UTC_TIMESTAMP();"); 
$result = $q -> execute(array(":id" => $this->id, ":token" => $token)); 
... 

Когда это работает, я получаю следующее сообщение об ошибке:

Caught exception: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?), tokenDate = UTC_TIMESTAMP()' at line 1 

Я не эксперт в MySQL, но я не мог найти любой синтаксис ошибки в моем коде, и я хотел бы помочь.

+1

Функция 'values ​​()' НЕ должна иметь свой собственный заполнитель или дубликат. просто используйте имя поля, в котором вы указали значение изначально: 'insert into ... (foo, ...) values ​​($ foo, ...) для дублированного набора ключей foo = values ​​(foo)'. mysql рассмотрит раздел 'values ​​($ foo, ....)' и вытащит предоставленное там значение. –

ответ

4

Как указано под PDO::prepare:

You must include a unique parameter marker for each value you wish to pass in to the statement when you call PDOStatement::execute() . You cannot use a named parameter marker of the same name more than once in a prepared statement, unless emulation mode is on.

Хотя вы можете добавить :token2 заполнитель или подобное, что случается быть связан с тем же значением, фактически VALUES() функции MySQL в предложении ON DUPLICATE KEY UPDATE принимает имя столбца не буквальный , Поэтому это будет делать трюк:

$q = $dbh->prepare(' 
    INSERT INTO email_confirm 
    (UserID, token, tokenDate) 
    VALUES 
    (:id, :token, UTC_TIMESTAMP()) 
    ON DUPLICATE KEY UPDATE 
    token = VALUES(token), 
    tokenDate = UTC_TIMESTAMP() 
'); 

Однако, вы можете захотеть взглянуть на Automatic Initialization and Updating for TIMESTAMP and DATETIME, а не пытаться переописать колесо.