程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++完成Oracle存儲過程批量插入(一)

C++完成Oracle存儲過程批量插入(一)

編輯:C++入門知識

C++完成Oracle存儲過程批量插入(一)


為了滿足大數據量的批量插入這個需求,最近研究了一下Oracle數據庫的批量插入這塊兒,本篇先介紹一下這兩天來所了解到的以及一次不成功的C++進行存儲過程批量插入方案。

一.Oracle處理批量插入存儲過程

1.Oracle處理批量插入涉及到的相關概念有:Type、bulk collect、Oracle數組等。現在對它們依次簡單的介紹一下。

1)Type

Type主要用於用戶建立Oracle自定義類型。

Type常用的自定義類型介紹:

A.子類型

類似與全局定義的常量,只要改一處地方,與此常量相關的地方都修改了。一般子類型常用於貨幣類型的定義,如number(10,5),我們可以定義子類型:subtype hb_num is number(10,5),這樣貨幣的精度需要修改時,不用搜遍全部地方,只需進行一處修改即可。

B.Object類型

定義了一個員工類

create or replace type type_employee as object(
id varchar2(36),
name varchar2(50),
age integer(3),
experience varchar2(4000)
);
可以使用該類型創建表,如下:

create table employee of type_employee
--則創建出了員工表
使用該Object類型,還可以創建其他類型,如下

--創建數組類型
create or replace type type_employee_arr as table of type_employee
更多詳細的內容請看:Oracle Type介紹

2)oracle數組

A.固定數組

type v_arr is varray(10) of varchar2(50);

B.可變數組

type v_arr is table of varchar2(50);

C.多維數組

--下面的定義如同1)中的創建數組的情況,不過兩者作用的范圍不同
--以object對象建立的數組可用作任何地方
--以表定義的type不能定義全局的type,只可在函數、存儲過程定義變量處定義
type v_table is table of poco_test%rowtype index by binary_integer;
3)bulk collect

bulk collect用於一次取出一個數據集合,比游標取數據效率高,但是其需要大量的內存,可以使用select into、fetch into、returning into語句到bulk collect中

declare
	type v_table is table of poco_test%rowtype index by binary_integer;
	v_values v_table;
begin
	select * bulk collect into v_values from poco_test;
end;
2.了解了相關的基本內容後,下面為本次研究Oracle批量插入的示例代碼

create or replace type poco_test_object_type as
object( id varchar2(36),
name varchar2(200),code varchar(200));
create or replace type poco_test_object_arr_type
as table of poco_test_object_type;
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 poco_test_arr_pro;

declare
 abc poco_test_object_arr_type;
 o poco_test_object_type;
begin
 o:=poco_test_object_type(1,2,3);
 abc:=poco_test_object_arr_type(o,o,o);
 poco_test_arr_pro(abc);
end;

二、JDBC調用參數為數組類型的存儲過程示例代碼

public class PocoTestModel
{
	private String id;
	private String name;
	private String code;
	........
}
Connection con = null;  
CallableStatement cstmt = null;       
try {                 
	con = OracleConnection.getConn();  
	List orderList = new ArrayList();  
	for(int i=0;i<100000;i++){  
		orderList.add(new PocoTestModel(UUID.randomUUID().toString(),"name"+i,"code"+i));  
	}              
	StructDescriptor recDesc = StructDescriptor.createDescriptor("poco_test_object_type", con);  
	ArrayList pstruct = new ArrayList();  
	for (PocoTestModel ord:orderList) {                  
		Object[] record = new Object[3];  
		record[0] = ord.getId();  
		record[1] = ord.getName();  
		record[1] = ord.getCode();  
		STRUCT item = new STRUCT(recDesc, con, record);                  
		pstruct.add(item);  
	}             
	ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("poco_test_object_arr_type", con);              
	ARRAY vArray = new ARRAY(tabDesc, con, pstruct.toArray());                     
	cstmt = con.prepareCall("{call poco_test_arr_pro(?)}");       
	cstmt.setArray(1, vArray);                   
	cstmt.execute();  
	con.commit();  
}catch ....
通過繼承oracle.sql.ORAData接口,實現toDatum函數,可以簡化執行的代碼編寫

public class PocoTestModel implements ORAData {
	private String id;
    private String name;
    private String code;
   
    public static final String _ORACLE_TYPE_NAME = "poco_test_object_type";   
	
    protected MutableStruct _struct;
    static int[] _sqlType = { OracleTypes.VARCHAR, OracleTypes.VARCHAR };
    static ORADataFactory[] _factory = new ORADataFactory[_sqlType.length];
	
    public PocoTestModel() {
        _struct = new MutableStruct(new Object[_sqlType.length], _sqlType, _factory);
    }
    public Datum toDatum(Connection conn) throws SQLException {
        _struct.setAttribute(0, this.id);
        _struct.setAttribute(1, this.name);
	_struct.setAttribute(1, this.code);
        return _struct.toDatum(conn, _ORACLE_TYPE_NAME);
    }
    public PocoTestModel(String id,String name, String code) {
        this();
        this.id = id;
        this.name = name;
	this.code = code;
    }
....
}

Connection con = null;
CallableStatement cstmt = null;     
try {     
	con = OracleConnection.getConn();           
	System.out.println(new Date());
	List orderList = new ArrayList();
	for(int i=0;i<100000;i++){
		orderList.add(new PocoTestModel(UUID.randomUUID().toString(),"name"+i,"code"+i));
	}        
	ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("poco_test_object_arr_type", con);            
	ARRAY vArray = new ARRAY(tabDesc, con, orderList.toArray());       
	
	cstmt = con.prepareCall("{call poco_test_arr_pro(?)}");     
	cstmt.setArray(1, vArray);               
	cstmt.execute();
	con.commit();
}catch ...

上面是所查到的Oracle批量插入的資料,關於C++方面,沒有找到像JDBC類似的方法,提供數組類型的參數的存儲過程的調用。下篇文章將介紹另外一個方案,來完成Oracle數據的批量插入。





  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved