Связывание PDO в foreach не выполняется при подготовке - PullRequest
0 голосов
/ 21 сентября 2018

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

Прежде всего, я определил sql query

$sql = '';

, затем я определил foreach значение цикла

$arrayLoopValue = 0;

, после этого у меня естьсоздал foreach цикл.В котором я увеличил arrayLoopValue, добавил sql к новому запросу на основе индекса массива.

foreach($questionsArray as $questionAnswerRow){
    $arrayLoopValue = $arrayLoopValue + 1;
    $sql = $sql .
    'INSERT INTO gosurveys_surveys_questions_answers
     SET survey_id = :survey_id_' . $arrayLoopValue .
    ', question_id = :question_id_' . $arrayLoopValue .
    ', user_email = :user_email_' . $arrayLoopValue .
    ', answer_type = :answer_type_' . $arrayLoopValue .
    ', question_answer = :question_answer_' . $arrayLoopValue .
    ', question_answer_creation_date = UTC_TIMESTAMP(); ';
  }

База данных / пример для этого запроса НЕ важна, так как все поля совпадают, и этоуже пусто.Требуется только структура, которая указана выше.

В следующей строке произойдет сбой.

$query = $this->conn->prepare($sql);

Я попытался echo запрос и посмотреть, если что-то не так.Я получил следующий вывод:

INSERT INTO gosurveys_surveys_questions_answers
     SET survey_id = :survey_id_1, 
     question_id = :question_id_1, 
     user_email = :user_email_1, 
     answer_type = :answer_type_1, 
     question_answer = :question_answer_1, 
     question_answer_creation_date = UTC_TIMESTAMP(); 

INSERT INTO gosurveys_surveys_questions_answers
     SET survey_id = :survey_id_2, 
     question_id = :question_id_2, 
     user_email = :user_email_2, 
     answer_type = :answer_type_2, 
     question_answer = :question_answer_2, 
     question_answer_creation_date = UTC_TIMESTAMP();

Что правильно.После этой подготовки есть второй цикл foreach.Но функция НЕ достигает после оператора prepare.

Я хотел бы знать причину.MYSQL говорит следующее:

Неполученное исключение «PDOException» с сообщением «SQLSTATE [42000]: синтаксическая ошибка или нарушение прав доступа: 1064 В синтаксисе SQL есть ошибка;обратитесь к руководству, соответствующему вашей версии сервера MySQL, чтобы узнать правильный синтаксис для использования возле 'INSERT INTO gosurveys_surveys_questions_answers SET survey_id =?, Ques'

Ответы [ 3 ]

0 голосов
/ 21 сентября 2018

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

$sql = 'INSERT INTO gosurveys_surveys_questions_answers
SET survey_id = :survey_id,
question_id = :question_id,
user_email = :user_email,
answer_type = :answer_type,
question_answer = :question_answer,
question_answer_creation_date = UTC_TIMESTAMP()';

$query = $this->conn->prepare($sql);

foreach($questionsArray as $questionAnswerRow) {
    $query->execute([
        ":survey_id" => $questionAnswerRow["survey_id"],
        // etc.
    ]);
}
0 голосов
/ 21 сентября 2018

Имя параметра не имеет значения.

Если вы хотите выполнить запрос более одного раза, то его подготовка - отличная идея, но имена параметров практически не имеют значения.важно связать новые значения с параметрами.

Итак, давайте предположим, что это ваш запрос

$sql = "INSERT INTO gosurveys_surveys_questions_answers
            SET survey_id = :a,
            question_id = :b,
            user_email = :c,
            answer_type = :d,
            question_answer = :e,
            question_answer_creation_date = UTC_TIMESTAMP()";

Обратите внимание, что имена параметров не имеют значения, если они уникальны вСтрока запроса.

Итак, теперь вы готовите этот запрос.Это передает базовый запрос в базу данных, где он компилируется и оптимизируется, но фактически не выполняется.

$stmt = $this->conn->prepare($sql);

Теперь в цикле, который получает параметр, вы можете выполнить этот подготовленный запрос 1000, 1 000 000 раз, есливам нравится, все, что вам нужно сделать, это привязать новые значения к параметрам и выполнить запрос, который передает значения параметров в уже подготовленный (скомпилированный и оптимизированный запрос) и запускает его с данными, которые вы передаете по execute()

foreach($inArray as $array) {
    // build the array of parameters and values

    $params = [ ':a' => $array['field1']
                ':b' => $array['field2']
                ':c' => $array['field3']
                ':d' => $array['field4']
                ':e' => $array['field5']
                ];

    // execute the prepared query using the new parameters
    $stmt->execute($params);
}
0 голосов
/ 21 сентября 2018

вот способ вставить несколько строк данных, вы готовите один раз и вставляете execute несколько раз один подготовленный оператор

$dbh = new PDO($dsn, $user, $pass, $options);
$arrayOfData = [...];
$stmt = $dbh->prepare('INSERT INTO table SET col = :val');
$dbh->beginTransaction();
foreach($arrayOfData as $data) {
  $stmt->bindValue(':val', $data);
  $stmt->execute();
}
$dbh->commit();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...