大數據量批量插入 Oracle,需繞過單條 INSERT 的網絡開銷。方案:定義 Oracle 對象類型與數組類型,存儲過程接收數組參數批量寫入,C++ (OCI) 構造數組並調用。
-- 1. 對象類型
CREATE OR REPLACE TYPE poco_test_object_type AS OBJECT (
id VARCHAR2(36), name VARCHAR2(200), code VARCHAR2(200)
);
-- 2. 數組類型
CREATE OR REPLACE TYPE poco_test_object_arr_type AS TABLE OF poco_test_object_type;
-- 3. 存儲過程
CREATE OR REPLACE PROCEDURE poco_test_arr_pro(v_arr IN poco_test_object_arr_type) IS
test_obj poco_test_object_type;
BEGIN
FOR idx IN v_arr.FIRST..v_arr.LAST LOOP
test_obj := v_arr(idx);
INSERT INTO poco_test VALUES(test_obj.id, test_obj.name, test_obj.code);
END LOOP;
END;
StructDescriptor recDesc = StructDescriptor.createDescriptor("poco_test_object_type", conn);
ArrayList<STRUCT> pstruct = new ArrayList<>();
for (PocoTestModel ord : orderList) {
Object[] record = {ord.getId(), ord.getName(), ord.getCode()};
pstruct.add(new STRUCT(recDesc, conn, record));
}
ArrayDescriptor arrDesc = ArrayDescriptor.createDescriptor("poco_test_object_arr_type", conn);
ARRAY vArray = new ARRAY(arrDesc, conn, pstruct.toArray());
CallableStatement cstmt = conn.prepareCall("{call poco_test_arr_pro(?)}");
cstmt.setArray(1, vArray);
cstmt.execute();
OCI 無現成 STRUCT/ARRAY 封裝,需手動:
OCIType 描述符(OCITypeByName)。OCICollection(數組)並逐元素 OCICollAppend 對象。OCIObjectNew + OCIObjectSetAttr。OCIStmt 執行 OCIStmtExecute。代碼量大且易錯,建議封裝通用類。若項目允許,優先考慮 OCIStmtExecute 批量執行 INSERT ... VALUES (:1,:2,:3) 配合 OCIBindByPos 綁定數組(OCI_ATTR_MAXDATA_SIZE),比存儲過程更簡單高效。
將介紹基於 OCI 直接批量綁定的方案,避開存儲過程與自定義類型的複雜性。