在我的SQL查询中,我在一个查询中有一个INSERT
,UPDATE
和一个SELECT
查询,如下面的查询
INSERT INTO questions (user_mail, question_id, question, username, created_at) VALUES (:fid, :qid, :com, :pid, :dat);
UPDATE users SET activity = activity + 1 WHERE face_id = :fid;
SELECT questions.face_id
FROM questions
WHERE questions.question_id = :qid
我在一个单独的PDO查询中拥有所有这三个查询但是有一个奇怪的规则使用UPDATE
查询$result = $stmt->fetchAll();
任何有关如何解决这个问题的想法,因为我的PDO不断吐出错误那说
SQLSTATE [HY000]:常规错误
这是组合查询的结果;并请它强制我组合上面的查询,否则我将不得不改变我的整个代码逻辑,其次我已经使用$result = $stmt->execute ( $params );
执行查询,但它返回SELECT
查询中的值我需要使用$stmt->fetchAll();
的部分。还有另一种方式吗?
另一种方式导致另一个问题
在其他未缓冲的查询仍处于活动状态时无法执行查询
case PUT_COMMENTS :
$this->querymultiple ['insert'] = "INSERT INTO talks (face_id, comment, phone_id, created_at) VALUES (:fid, :com, :pid, :dat);";
$this->querymultiple ['update'] = "UPDATE facelog SET activity = activity + 1 WHERE face_id = :fid;
UPDATE facelog SET commentCount = commentCount + 1 WHERE face_id = :fid;";
$this->querymultiple ['select'] = "SELECT
talks.comment,
talks.face_id,
userlog.gcm_id
FROM
talks,
tagged,
userlog
WHERE
talks.face_id = :fid
AND talks.comment = :com
AND tagged.face_id = talks.face_id
AND userlog.phone_id = tagged.phone_id";
$this->params ['insert'] = array (
':' . FACE_ID => $value [FACE_ID],
':' . COMMENT => $value [COMMENT],
':' . DATE => $value [DATE],
':' . PHONE_ID => $value [PHONE_ID]
);
$this->params ['update'] = array (
':' . FACE_ID => $value [FACE_ID]
);
$this->params ['select'] = array (
':' . FACE_ID => $value [FACE_ID],
':' . COMMENT => $value [COMMENT]
);
$this->pdo_query->RunMultipleQuery ( $tag, $this->querymultiple, $this->params, SELECT );
break;
我的RunMultipleQuery()
方法如下
/**
* This method runs multiple the Queries
*
* @param unknown $tag
* @param unknown $query
* @param unknown $params
* @param unknown $query_type
*/
public function RunMultipleQuery($tag, $query, $params, $query_type) {
try {
$stmt = array ();
$result = array ();
if (! empty ( $query ) || ! empty ( $params )) {
$this->pdo_db->pdo_db->beginTransaction ();
$stmt ['insert'] = $this->pdo_db->pdo_db->prepare ( $query ['insert'] );
$stmt ['update'] = $this->pdo_db->pdo_db->prepare ( $query ['update'] );
$stmt ['select'] = $this->pdo_db->pdo_db->prepare ( $query ['select'] );
$result ['insert'] = $stmt ['insert']->execute ( $params ['insert'] );
$result ['update'] = $stmt ['update']->execute ( $params ['update'] );
$result ['select'] = $stmt ['select']->execute ( $params ['select'] );
$stmt ['insert']->closeCursor ();
$stmt ['update']->closeCursor ();
$stmt ['select']->closeCursor ();
$this->pdo_db->pdo_db->commit ();
} else {
$result = null;
}
} catch ( PDOException $e ) {
// For testing, you could use a die and message.
// die("Failed to run query: " . $ex->getMessage());
// or just use this use this one to product JSON data:
// $response["message"] = '0:'.$ex->getMessage() ;
// die(json_encode($response["message"]));
$error_message = $e->getMessage ();
$error_code = $e->getCode ();
$error_trace = $e->getTrace ();
Log::LogError ( $error_message, $error_code, $error_trace );
// roll back transaction
if ($this->pdo_db->pdo_db->inTransaction ()) {
$this->pdo_db->pdo_db->rollBack ();
}
$result = null;
}
if ($query_type == SELECT) {
// echo 'result = '.$result;
try {
if (! empty ( $result ['select'] )) {
// fetching all the rows from the query
SendtoClient::Toclient ( $tag, $stmt ['select']->fetchAll () );
} else {
SendtoClient::Toclient ( $tag, null );
}
} catch ( PDOException $e ) {
$error_message = $e->getMessage ();
$error_code = $e->getCode ();
$error_trace = $e->getTrace ();
Log::LogError ( $error_message, $error_code, $error_trace );
}
}
}
答案 0 :(得分:2)
我将发布一个示例,说明如何使用预准备语句执行此操作:
try
{
$pdo->beginTransaction();
$stmt['insert'] = $pdo->prepare("INSERT INTO questions (user_mail, question_id, question, username, created_at) VALUES (:fid, :qid, :com, :pid, :dat)");
$stmt['update'] = $pdo->prepare("UPDATE users SET activity = activity + 1 WHERE face_id = :fid");
$stmt['select'] = $pdo->prepare("SELECT questions.face_id FROM questions WHERE questions.question_id = :qid");
$stmt['insert']->execute([':fid' => 'your value', ':qid' => 'your value', ':com' => 'your value', ':pid' => 'your value', ':dat' => 'your value']);
$stmt['update']->execute([':fid' => 'your value']);
$stmt['select']->execute([':qid' => 'your qid']);
$rows = $stmt['select']->fetchAll();
$pdo->commit();
}
catch(\PDOException $e)
{
echo "Something went terribly wrong: " . $e->getMessage();
if($pdo->inTransaction())
{
$pdo->rollBack();
}
}
您不应该在单个PDO函数中发送表示3个查询的字符串的原因是:它不起作用。 第二个原因是:调试或维护类似的东西很困难。对每种类型的作业进行查询要清晰得多。 第三个原因:假设三个查询可以一起工作,你怎么知道哪一个失败?
使用预准备语句可以很好地控制此流程。使用事务确保一切按计划进行 - 如果某些事情在此过程中死亡,则数据库不会因孤立数据而损坏。最好的部分 - 您可以捕获异常并检查其错误消息,以查看哪个查询失败。
我发布了一个代码示例,您应该使用计划发送到数据库的值对其进行修改。从性能POV来看,它稍微慢一点(除非你发出很多查询,在这种情况下它非常快)。