PDO的规则与UPDATE和FETCHALL()

时间:2015-07-20 14:52:32

标签: php mysql pdo

在我的SQL查询中,我在一个查询中有一个INSERTUPDATE和一个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 );
        }
    }
}

1 个答案:

答案 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来看,它稍微慢一点(除非你发出很多查询,在这种情况下它非常快)。