萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

PHP mysql_data_seek() 函數詳解:結果集指標移動、重複遍歷與避坑指南

函數簽名與用途

bool mysql_data_seek ( resource $result , int $row_number )
  • 將 mysql_query() 返回的結果集內部行指標移動到指定行號 (0-based)
  • 後續 mysql_fetch_row() / mysql_fetch_assoc() / mysql_fetch_array() 將從該行開始讀取
  • **僅支援緩衝查詢結果** (mysql_query),**不支援** mysql_unbuffered_query

參數詳解

參數類型說明
$resultresourcemysql_query() 返回的結果集資源
$row_numberint目標行號,**0 = 第一行**,範圍 [0, mysql_num_rows($result) - 1]

返回值

  • true:移動成功
  • false:失敗 (行號超出範圍、結果集為空、非緩衝結果集)

完整範例:雙重遍歷同一結果集

$conn = mysql_connect('localhost', 'root', 'root');
mysql_query("SET NAMES gbk");
mysql_select_db('pw8', $conn);

$sql = "SELECT * FROM shop_district";
$result = mysql_query($sql, $conn);  // 必須是緩衝查詢

// 第一次遍歷
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
    printf("ID: %s  FID: %s  Name: %s\n", $row[0], $row[1], $row[2]);
}

// 重置指標到第 0 行
mysql_data_seek($result, 0);

// 第二次遍歷 (同一結果集,無需再次查詢)
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
    printf("ID: %s  FID: %s  Name: %s\n", $row[0], $row[1], $row[2]);
}

mysql_free_result($result);
mysql_close($conn);

常見錯誤與避坑

錯誤現象原因解決
Warning: mysql_data_seek(): Offset 0 is invalid for MySQL result結果集為空 (mysql_num_rows() == 0)先判斷 if (mysql_num_rows($result) > 0) 再 seek
Warning: mysql_data_seek(): supplied argument is not a valid MySQL result resource傳入非 mysql_query 結果 (如 mysql_unbuffered_query、PDOStatement、mysqli_result)僅搭配 mysql_query 使用;mysqli 用 mysqli_data_seek(),PDO 用 scrollable cursor
行號超出範圍$row_number >= mysql_num_rows($result)邊界檢查:min($row_number, mysql_num_rows($result)-1)

現代替代方案 (mysqli / PDO)

// mysqli (支援緩衝/非緩衝雙模式)
$mysqli = new mysqli("localhost", "root", "root", "pw8");
$result = $mysqli->query("SELECT * FROM shop_district"); // 預設緩衝
$result->data_seek(0);  // 同樣功能
while ($row = $result->fetch_row()) { ... }

// PDO (需啟用游標)
$pdo = new PDO("mysql:host=localhost;dbname=pw8", "root", "root", [
    PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL
]);
$stmt = $pdo->query("SELECT * FROM shop_district");
$stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_FIRST); // 移至第一行
// 或 $stmt->scrollable = true 後用 fetch(PDO::FETCH_ORI_ABS, $offset)

效能提示

  • 結果集極大時,mysql_data_seek 只是移動指標,**不重讀磁碟**,極快
  • 但整個結果集已載入 PHP 記憶體,**大結果集慎用緩衝查詢**,改用非緩衝/游標分批處理
  • PHP 7.0+ **已移除 mysql_* 擴展**,新專案**務必使用 mysqli 或 PDO**
copyright © 萬盛學電腦網 all rights reserved