PHP PDO UPDATE оператор с подзапросом - PullRequest
0 голосов
/ 24 апреля 2018

Я пытаюсь создать запрос, используя PDO, где запрос включает подзапрос. Код не работает. Используя верстак, я могу выполнить запрос, и он выполняет.

Я чувствую, что здесь есть нюанс, когда речь идет о получении таблицы при использовании PDO.

    $turn = 1;
    $phase = -1;
    $status = "waiting";
    $gameid = 1;

        $stmt = $this->connection->prepare("
            UPDATE playerstatus 
            SET 
                turn = :turn,
                phase = :phase,
                status = :status,
                value = value + (SELECT reinforce FROM games where id = :gameid)
            WHERE
                gameid = :gameid                
        ");

        $stmt->bindParam(":turn", $turn);
        $stmt->bindParam(":phase", $phase);
        $stmt->bindParam(":status", $status);
        $stmt->bindParam(":gameid", $gameid);

        $stmt->execute();

Я перепробовал множество настроек, они просто не выполняются.

Ошибка редактирования:

Неустранимая ошибка: необработанное исключение PDO: SQLSTATE [HY093]: неверный номер параметра

1 Ответ

0 голосов
/ 24 апреля 2018

Известное (но недостаточно документированное) ограничение с именованными плашдолами PDO: один и тот же заполнитель связывания не может использоваться более одного раза в утверждении.Обходной путь должен использовать отличные имена заполнителя связывания.

(Это ограничение в PDO, возможно, было устранено в более поздних версиях (?). Я думаю, что основная причина заключается в том, что "за кадром", PDO заменяет именные заполнители на вопросительные знаки позиционной нотации. Эта проблемане ограничивается только инструкциями UPDATE, эта же проблема преследует все операторы SQL PDO с использованием именованных заполнителей.)


Кроме того, я не рекомендую использовать bindValue вместо bindParam, а *1006*..

Измените имя заполнителя привязки, чтобы оно было уникальным.Здесь показано изменение одного из вхождений :gameid на :gameid2

           value = value + (SELECT reinforce FROM games where id = :gameid)
        WHERE
            gameid = :gameid2
                            ^

И нам необходимо указать значение для каждого заполнителя привязки.Это означает, что нам нужно добавить еще одну строку.С bindValue мы можем ссылаться на одну и ту же переменную без необходимости ее копирования.

    $stmt->bindValue(":gameid", $gameid);
    $stmt->bindValue(":gameid2", $gameid);
                             ^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...