首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

ODAC 應用技巧 (四):高效存取 VARRAY 集合型別

     編輯:Oracle 資料庫基礎

前言

Oracle Collection 型別 (VARRAY、Nested Table) 在 PL/SQL 與應用層交互時常見。ODAC 提供 TArrayField、TOraArray 等機制映射集合元素,但大型陣列會產生大量 TField 導致效能下降。本文說明 ODAC 陣列存取限制、三種存取模式、參數綁定與效能優化策略。

一、ODAC 陣列映射限制

  • 預設單一欄位最大建立 1,000 個 TField 子欄位 (對應 VARRAY 最大元素數)。
  • 超過限制時,設計時欄位編輯器將截斷,運行時需透過 TOraArray 物件存取完整元素。

二、範例型別與資料表

CREATE TYPE tdac_array1 AS VARRAY(5) OF NUMBER;
CREATE TYPE tdac_array2 AS VARRAY(4) OF CHAR(10);

CREATE TABLE odac_array (
  code  NUMBER,
  title VARCHAR2(10),
  arr1  tdac_array1,
  arr2  tdac_array2
);

三、三種陣列元素存取方式

方式 1:FieldByName 直接索引 (需 ObjectField=True)

// 存取 arr1 第 1 個元素 (0-based)
var
  v: Integer;
begin
  v := Query.FieldByName('Arr1[0]').AsInteger;  // 簡單直接
end;

方式 2:TArrayField 物件導向存取

var
  v: Integer;
  arrField: TArrayField;
begin
  arrField := TArrayField(Query.FieldByName('Arr1'));
  v := arrField.Fields[0].AsInteger;  // Fields 為 TField 陣列
end;

方式 3:TOraArray 統一介面 (推薦大型陣列/高效能)

var
  v: Integer;
  oraArr: TOraArray;
begin
  oraArr := Query.GetArray('Arr1');  // 取得 TOraArray 物件
  v := oraArr.ItemAsInteger[0];      // 強型別索引器
  // 或動態名稱存取
  v := oraArr.AttrAsInteger['[1]'];
end;
優勢:TOraArray 直接操作底層 OCI 集合控制碼,避免建立大量 TField 物件,記憶體佔用低、存取速度快。

四、SparseArray 模式 (按需載入)

Query.SparseArray := True;  -- 僅在存取時載入該元素
// 配合 TArrayField.Fields[Index] 使用
v := TArrayField(Query.FieldByName('Arr1')).Fields[100].AsInteger;  // 只載入第 101 個
  • 適用於大型 VARRAY (如 1000+ 元素) 但應用僅存取少數元素的場景。
  • 減少網路傳輸與客戶端記憶體壓力。

五、SQL/PLSQL 參數綁定 VARRAY

建立參數並指定型別

var
  OraSQL: TOraSQL;
begin
  OraSQL.SQL.Text := 'INSERT INTO odac_array (Code, Arr1, Arr2) VALUES (:Code, :Arr1, :Arr2)';
  OraSQL.ParamByName('Code').AsInteger := 10;

  // 綁定 Arr1 (NUMBER VARRAY)
  with OraSQL.ParamByName('Arr1').AsArray do begin
    AllocObject(OraSession.OCISvcCtx, 'TDAC_ARRAY1');  // 指定資料庫型別名
    ItemAsInteger[0] := 12;
    AttrAsInteger['[1]'] := 10;   // 別名索引
    ItemAsInteger[3] := 133;
  end;

  // 綁定 Arr2 (CHAR VARRAY)
  with OraSQL.ParamByName('Arr2').AsArray do begin
    OCISvcCtx := OraSession.OCISvcCtx;
    AllocObject('TDAC_ARRAY2');
    AttrAsString['[2]'] := 'eeee';
    ItemAsString[0] := 'FFFFF';
  end;

  OraSQL.Execute;
end;

關鍵屬性/方法對照

屬性/方法用途適用型別
AsArray取得集合參數介面dtArray
AllocObject(SvcCtx, TypeName)在 Server 端分配集合物件實例所有
ItemAsInteger[Index]強型別整數索引存取NUMBER VARRAY
ItemAsString[Index]強型別字串索引存取CHAR/VARCHAR2 VARRAY
AttrAsInteger['[Index]']字串鍵名動態索引存取NUMBER VARRAY
AttrAsString['[Index]']字串鍵名動態索引存取CHAR/VARCHAR2 VARRAY

六、效能優化建議

  1. 優先 TOraArray:大型集合 (>100 元素) 必須使用 GetArray + TOraArray,避免 TField 爆炸。
  2. 啟用 SparseArray:稀疏存取場景設定 Query.SparseArray := True。
  3. 批次綁定:TOraSQL / TOraQuery 支援陣列 DML (Execute(Iters)),單次網路往返插入多筆含集合的記錄。
  4. 型別快取:AllocObject 的型別名稱 (如 'TDAC_ARRAY1') 為資料庫型別名稱 (大小寫敏感),建議常數化管理。

七、總結

ODAC 透過 TArrayField (設計時友善) 與 TOraArray (運行時高效) 雙軌支援 VARRAY 存取。核心決策樹:元素數 ≤ 20 且全量存取 → FieldByName/TArrayField;元素數大/稀疏存取/高效能需求 → TOraArray + SparseArray。參數綁定時務必正確呼叫 AllocObject 指定 Server 端型別,並區分 ItemAsXxx (整數索引) 與 AttrAsXxx (字串鍵) 兩種存取介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved