五大游標類型總覽
| 類型 | 可捲動 | 可更新 | 成員資格 | 效能 | 適用場景 |
| 基底表游標 | 雙向 | 是 | 動態(即時看見同交易內插入/刪除/更新) | 最快(直接儲存引擎) | 單表/索引直接存取、高頻更新 |
| 靜態游標 | 雙向 | 否 | 靜態(開啟時快照,不見外部變更) | 較慢、佔記憶體 | 需捲動但不更新、鍵集不適用時 |
| 前進游標 | 僅前向 | 是 | 動態(擷取前可見變更,擷取後不可見) | 最快(查詢型) | 單向讀取、優先速度/記憶體 |
| 前進/唯讀游標 | 僅前向 | 否 | 動態 | 最快(絕對) | 唯讀單向掃描 |
| 鍵集驅動游標 | 雙向 | 是 | 開啟時固定鍵集(書籤),成員固定 | 中等 | 需捲動更新、聯結查詢 |
各類型詳細特性與 ADO.NET 程式碼
1. 基底表游標
- 直接在資料表/索引上開啟,不支援查詢結果集(如
SELECT * FROM t)。
- 可指定索引以利排序、範圍搜尋。
- 動態成員:同一資料表開啟的兩個游標,在同一交易範圍內即時看見彼此變更。
// 基底表游標
cmd.CommandText = "tablename";
cmd.CommandType = CommandType.TableDirect;
SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Updatable);
// 索引游標
cmd.CommandText = "tablename";
cmd.IndexName = "indexname";
cmd.CommandType = CommandType.TableDirect;
SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Updatable);
2. 靜態游標
- 建立結果集完整副本(延遲填充長資料),支援雙向捲動、唯讀。
- 不見外部變更,生命週期內快取查詢結果。
- 較前進游標慢、佔記憶體,僅在需捲動且鍵集不適用時使用。
cmd.CommandText = "SELECT * FROM tablename";
SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Insensitive);
3. 前進游標
- 可更新、不可捲動、速度最快(查詢型)。
- 擷取前可見所有已認可變更;擷取後無法回頭看見後續變更。
cmd.CommandText = "SELECT * FROM tablename";
SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Updatable); // 預設前進
4. 前進/唯讀游標
- 最快、不可更新、不可捲動。
- 注意:若查詢僅回傳唯讀欄位(如聯結衍生欄),無法建立,會擲回「無可更新欄位」錯誤。
cmd.CommandText = "SELECT * FROM tablename";
SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.None);
5. 鍵集驅動游標
- 可捲動、可更新。鍵集 = 開啟時符合條件列的書籤集合(非唯一鍵值),儲存於暫存表。
- 對鍵集內資料值變更(內部/外部)皆可見;插入僅在游標內可見,外部插入需重開游標或改用前進游標;刪除嘗試擷取時回報已刪除。
- 與 SQL Server 完整版差異:完整版用唯一鍵值,Compact 用書籤。
cmd.CommandText = "SELECT * FROM tablename";
SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Updatable);
聯結查詢上的鍵集游標限制
- 聯結衍生欄位不可更新(可插入新值但不支援 UPDATE)。
- 若繫結至可更新控制項(如 DataGrid),必須將聯結欄位設為唯讀,否則更新失敗。
選型決策樹
- 需直接存取資料表/索引、最高效能 → 基底表游標。
- 需雙向捲動 + 更新 → 鍵集驅動(聯結謹慎)或 靜態(唯讀)。
- 單向掃描 + 更新 → 前進游標。
- 單向掃描 + 唯讀 → 前進/唯讀游標。
- 需看見外部即時插入 → 僅基底表/前進游標;鍵集/靜態不可見。