我想创建一个查询,该查询可以包含一个或多个部分。这意味着,我将包含一个数组并对其进行遍历,并将查询附加到主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 =?,问题'
答案 0 :(得分:2)
参数名称并不重要。
如果您想多次运行查询,那么准备它是一个好主意,但是参数名称几乎无关紧要。重要的是将新值绑定到参数。
因此,假设这是您的查询
drivers
请注意,只要参数名称在查询字符串中是唯一的,它们就无关紧要。
因此,现在您准备该查询。这样会将基本查询传递到数据库中,在该数据库中对其进行编译和优化,但实际上并未运行。
ALTER TABLE drivers ADD INDEX (name);
现在,在可以获取参数的循环中,您可以运行准备好的查询1000次,如果需要,可以运行1,000,000次,您所要做的就是将新值绑定到参数并执行查询,该查询将参数值传递给已经准备好(经过编译和优化的查询),并与您在$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);
答案 1 :(得分:1)
这是插入多行数据的方法,您准备一次,然后多次插入// class declaration
public class FragmentTopNews extends Fragment
implements LoaderManager.LoaderCallbacks<List<NewsItem>>, NewsAdapter.OnItemClickListener{
...
if(activeNetwork != null && activeNetwork.isConnected()){
LoaderManager loaderManager = getLoaderManager();
loaderManager.initLoader(NEWS_LOADER_ID, null,this);
}
// SwipeRefreshlayout for refreshing the data
mSwipeRefreshLayout = rootView.findViewById(R.id.srl_refresher);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mNewsAdapter.clearData();
mNewsAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(true);
// Here is the problem
getLoaderManager().restartLoader(NEWS_LOADER_ID, null, this);
}
});
一条准备好的语句
execute
答案 2 :(得分:1)
准备好的语句的思想是该语句准备一次,然后执行多次。像这样:
$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.
]);
}