當前位置: 首頁> 最新文章列表> 在CodeIgniter 中結合next_result() 處理多語句查詢

在CodeIgniter 中結合next_result() 處理多語句查詢

gitbox 2025-05-06

在使用CodeIgniter(特別是CodeIgniter 3)開發過程中,有時候我們需要執行包含多個SQL 查詢的語句塊(Multi-Query)。例如,我們可能希望一次性調用多個存儲過程,或在一個請求中執行多個查詢以提高效率。

但在使用多語句查詢時,一個常見問題是:只有第一個結果集可被訪問,其它結果集無法獲取。這是因為在使用MySQLi 驅動的情況下,CodeIgniter 並不會自動處理多個結果集。為了解決這個問題,我們就需要手動調用$this->db->next_result()方法來清理前一個結果集,並讓系統準備好處理下一個。

本文將向你展示如何在CodeIgniter 中正確使用next_result()來處理多語句查詢。

基礎示例:使用multi_querynext_result()

假設你有一個存儲過程文件,或者直接在控制器中執行類似如下的SQL:

 $sql = "
    CALL get_users(); 
    CALL get_orders();
";

為了執行這類多語句SQL,你可以使用query()方法並手動管理結果集:

 $result = $this->db->query("CALL get_users();");

if ($result) {
    $users = $result->result();

    // 清理第一個結果集
    $result->free_result();
    $this->db->next_result();

    // 獲取第二個結果集
    $result2 = $this->db->query("CALL get_orders();");

    if ($result2) {
        $orders = $result2->result();

        // 再次清理
        $result2->free_result();
        $this->db->next_result();
    }
}

這種方式適用於每次只調用一個存儲過程,然後再手動執行下一條語句。但若你希望一次性執行多個SQL 語句,比如用以下方式:

 $sql = "
    CALL get_users(); 
    CALL get_orders(); 
    CALL get_products();
";

則可以藉助MySQLi 原生的multi_query()功能實現。

使用MySQLi 的multi_query方法

在CodeIgniter 中,如果你使用的是MySQLi 驅動,你可以這樣操作:

 $mysqli = $this->db->conn_id; // 獲取底層的 MySQLi 連接資源

$sql = "
    CALL get_users(); 
    CALL get_orders(); 
    CALL get_products();
";

if ($mysqli->multi_query($sql)) {
    do {
        if ($result = $mysqli->store_result()) {
            // 處理當前結果集
            $data[] = $result->fetch_all(MYSQLI_ASSOC);
            $result->free();
        }
    } while ($mysqli->more_results() && $mysqli->next_result());
}

這段代碼會依次獲取多個結果集,並使用next_result()準備好下一個。

CodeIgniter 中正確的用法建議

雖然你可以直接用multi_query() ,但強烈建議將多語句分開執行,尤其是當你對安全性和穩定性有較高要求時。對於數據庫操作,推薦以下做法:

  1. 在每次查詢後調用free_result()next_result()清理連接。

  2. 避免在模型中直接寫多個CALL ,而是封裝為單個調用,邏輯控制放在PHP 層。

  3. 如果必須使用multi_query() ,確保你處理了所有返回的結果集,避免“Commands out of sync”錯誤。

示例:封裝成模型方法

你可以把這個過程封裝成模型方法,返回包含多個數據集的數組:

 public function get_multi_data()
{
    $mysqli = $this->db->conn_id;

    $sql = "
        CALL get_users(); 
        CALL get_orders(); 
        CALL get_products();
    ";

    $data = [];

    if ($mysqli->multi_query($sql)) {
        do {
            if ($result = $mysqli->store_result()) {
                $data[] = $result->fetch_all(MYSQLI_ASSOC);
                $result->free();
            }
        } while ($mysqli->more_results() && $mysqli->next_result());
    }

    return $data;
}

控制器中你可以這樣調用:

 $this->load->model('Data_model');
$result_sets = $this->Data_model->get_multi_data();

$users = $result_sets[0];
$orders = $result_sets[1];
$products = $result_sets[2];

小貼士:調試時注意日誌輸出

調試多語句查詢時,建議開啟CodeIgniter 的日誌功能,並觀察application/logs中的內容,便於排查錯誤。