Android 內建 SQLite **不支援 SQL Server/Access 的 `TOP n` 語法**,嘗試執行 `SELECT TOP 1 * FROM table` 會拋出 `SQLException: near "TOP": syntax error`。標準替代方案是使用 **`LIMIT` 子句**,語法兼容 PostgreSQL/MySQL/SQLite。
| 錯誤 (SQL Server/Access) | 正確 (SQLite/PostgreSQL/MySQL) |
SELECT TOP 1 * FROM history | SELECT * FROM history LIMIT 1 |
SELECT TOP 10 * FROM history ORDER BY id DESC | SELECT * FROM history ORDER BY id DESC LIMIT 10 |
SELECT TOP 5 * FROM history WHERE type=1 | SELECT * FROM history WHERE type=1 LIMIT 5 |
分頁查詢標準模式
// 第 1 頁 (每頁 20 筆)
SELECT * FROM history ORDER BY _id DESC LIMIT 20 OFFSET 0;
// 第 2 頁
SELECT * FROM history ORDER BY _id DESC LIMIT 20 OFFSET 20;
// 第 N 頁
SELECT * FROM history ORDER BY _id DESC LIMIT 20 OFFSET (N-1)*20;
Android `SQLiteDatabase.query()` 封裝:
Cursor cursor = db.query(
"history", // table
null, // columns (null = all)
null, // selection
null, // selectionArgs
null, // groupBy
null, // having
"_id DESC", // orderBy
"20 OFFSET " + offset // limit (包含 OFFSET)
);
效能優化提醒
- 大偏移量 (`OFFSET 100000`) 會掃描前 10 萬行再丟棄,**極慢**。
- **游標分頁 (Keyset Pagination)**:改用 `WHERE _id < lastSeenId ORDER BY _id DESC LIMIT 20`,無 OFFSET,效能恆定。
- 建立索引:`CREATE INDEX idx_history_id ON history(_id DESC);` 加速排序。
總結
Android SQLite **只認 `LIMIT`,不認 `TOP`**。記住 `SELECT * FROM table ORDER BY col DESC LIMIT pageSize OFFSET offset` 模板,大數據量分頁請改用游標分頁避免效能崩塌。
- 上一篇文章: SVN 更新後 JSP 報 NullPointerException:衝突解決與專案清理標準流程
- 下一篇文章: iReport 導出二維碼出現 Trial 浮水印:原因在於使用評試版 barcode.jar,解決方案與替代庫推薦
Copyright ©
程式碼之家 All Rights Reserved