pdo绑定在prepare时失败

dced5bon  于 2021-06-19  发布在  Mysql
关注(0)|答案(3)|浏览(265)

我想创建一个可能包含或不包含多个部分的查询。这意味着,我将包含一个数组并在其中循环,然后将一个查询附加到主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\u surveys\u questions\u answers set survey\u id=?,ques”附近使用的正确语法
9w11ddsr

9w11ddsr1#

参数的名称并不重要。
如果您想多次运行一个查询,那么准备它是一个很好的主意,但是参数名几乎是不相关的。重要的是将新值绑定到参数。
假设这是你的问题

$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、1000000次,所要做的就是将新值绑定到参数并执行查询,该查询将参数值传递给已经准备好的(已编译和优化的查询),并使用传递给 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);

}

kxeu7u2r

kxeu7u2r2#

下面是插入多行数据的方法,您只需准备一次并插入 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();
5kgi1eie

5kgi1eie3#

prepared语句的思想是先准备一次语句,然后执行多次。像这样:

$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.
    ]);
}

相关问题