`
awaitdeng
  • 浏览: 216926 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Oracle存储过程做大数据量插入

阅读更多
顶 
0
 
踩 最近在项目中用到了JAVA客户端传递对象数组到Oracle存储过程做大数据量插入,比如10万级别. 
下面做一个插入10万条记录的示例步骤,,为了容易理解,表的结果很简单. 
1,假设表结构如下: 
源码copy to clipboard打印?
01.CREATE TABLE UKBNOVCTCORDER(   
02.LosingLEName varchar2(200),   
03.LosingLECode varchar2(200)   
04.)  
CREATE TABLE UKBNOVCTCORDER(
LosingLEName varchar2(200),
LosingLECode varchar2(200)
)2,在数据库建立一个type,对应JAVA端要传入的对象结构: 
源码copy to clipboard打印?
01.CREATE OR REPLACE TYPE BUT_UKBNOV_CTC_ORDER_REC AS OBJECT (   
02.  losingLEName VARCHAR2(200),   
03.     losingLECode VARCHAR2(200)   
04.);  
CREATE OR REPLACE TYPE BUT_UKBNOV_CTC_ORDER_REC AS OBJECT (
  losingLEName VARCHAR2(200),
     losingLECode VARCHAR2(200)
);3,为了数组传输,建立一个数组类型的type: 
CREATE OR REPLACE TYPE BUT_UKBNOV_CTC_ORDER_TAB AS TABLE OF BUT_UKBNOV_CTC_ORDER_REC 
4,建立存储过程做插入工作: 
源码copy to clipboard打印?
01.CREATE OR REPLACE procedure bulkInsertCTDORDER(i_orders IN BUT_UKBNOV_CTC_ORDER_TAB)   
02.as   
03.ctcOrder BUT_UKBNOV_CTC_ORDER_REC;   
04.begin   
05.    FOR idx IN i_orders.first()..i_orders.last() LOOP   
06.        ctcOrder:=i_orders(idx);   
07.        INSERT INTO UKBNOVCTCORDER   
08.          (LosingLEName,   
09.           LosingLECode)   
10.        VALUES   
11.          (ctcOrder.losingLEName,   
12.           ctcOrder.losingLECode);   
13.    end loop;   
14.    exception when others then   
15.    raise;   
16.end;  
CREATE OR REPLACE procedure bulkInsertCTDORDER(i_orders IN BUT_UKBNOV_CTC_ORDER_TAB)
as
ctcOrder BUT_UKBNOV_CTC_ORDER_REC;
begin
    FOR idx IN i_orders.first()..i_orders.last() LOOP
        ctcOrder:=i_orders(idx);
        INSERT INTO UKBNOVCTCORDER
          (LosingLEName,
           LosingLECode)
        VALUES
          (ctcOrder.losingLEName,
           ctcOrder.losingLECode);
    end loop;
    exception when others then
    raise;
end;5,建立JAVA端java bean对象,(为节省版面,下面的get set方法省略,) 
源码copy to clipboard打印?
01.public class UkbnovCTCOrder  {   
02.    private String losingLEName;   
03.    private String losingLECode;   
04......  
public class UkbnovCTCOrder  {
    private String losingLEName;
    private String losingLECode;
.....在JAVA端访问存储过程插入数据,需要做JAVA数据类型和存储过程类型type的映射,下面的StructDescriptor是mapping Oracle端AS OBJECT类型, 
tabDesc 是mapping Oracle端数组 AS TABLE OF类型的. 
源码copy to clipboard打印?
01.Connection con = null;   
02.CallableStatement cstmt = null;        
03.try {                  
04.    con = OracleConnection.getConn();   
05.    List<UkbnovCTCOrder> orderList = new ArrayList<UkbnovCTCOrder>();   
06.    for(int i=0;i<100000;i++){   
07.        orderList.add(new UkbnovCTCOrder("losingLEName"+i,"losingLECode+"+i));   
08.    }               
09.    StructDescriptor recDesc = StructDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_REC", con);   
10.    ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();   
11.    for (UkbnovCTCOrder ord:orderList) {                   
12.        Object[] record = new Object[2];   
13.        record[0] = ord.getLosingLEName();   
14.        record[1] = ord.getLosingLECode();   
15.        STRUCT item = new STRUCT(recDesc, con, record);                   
16.        pstruct.add(item);   
17.    }              
18.    ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_TAB", con);               
19.    ARRAY vArray = new ARRAY(tabDesc, con, pstruct.toArray());                      
20.    cstmt = con.prepareCall("{call bulkInsertCTDORDER(?)}");        
21.    cstmt.setArray(1, vArray);                    
22.    cstmt.execute();   
23.    con.commit();  
        Connection con = null;
        CallableStatement cstmt = null;     
        try {               
            con = OracleConnection.getConn();
            List<UkbnovCTCOrder> orderList = new ArrayList<UkbnovCTCOrder>();
            for(int i=0;i<100000;i++){
                orderList.add(new UkbnovCTCOrder("losingLEName"+i,"losingLECode+"+i));
            }            
            StructDescriptor recDesc = StructDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_REC", con);
            ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();
            for (UkbnovCTCOrder ord:orderList) {                
                Object[] record = new Object[2];
                record[0] = ord.getLosingLEName();
                record[1] = ord.getLosingLECode();
                STRUCT item = new STRUCT(recDesc, con, record);                
                pstruct.add(item);
            }           
            ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_TAB", con);            
            ARRAY vArray = new ARRAY(tabDesc, con, pstruct.toArray());                   
            cstmt = con.prepareCall("{call bulkInsertCTDORDER(?)}");     
            cstmt.setArray(1, vArray);                 
            cstmt.execute();
            con.commit();6,如果每次调用都需要做Java bean的到Oracle的"AS OBJECT"类型的mapping,则很繁琐,可以然Java bean实现oracle.sql.ORAData,这样就不用在调用时候在做mapping了. 
java bean对象如下,为节省版面get set方法省略. 
源码copy to clipboard打印?
01.public class UkbnovCTCOrder1 implements ORAData {   
02.    private String losingLEName;   
03.    private String losingLECode;   
04.    public static final String _ORACLE_TYPE_NAME = "BUT_UKBNOV_CTC_ORDER_REC";      
05.    protected MutableStruct _struct;   
06.    static int[] _sqlType = { OracleTypes.VARCHAR, OracleTypes.VARCHAR };   
07.    static ORADataFactory[] _factory = new ORADataFactory[_sqlType.length];   
08.    public UkbnovCTCOrder1() {   
09.        _struct = new MutableStruct(new Object[_sqlType.length], _sqlType, _factory);   
10.    }   
11.    public Datum toDatum(Connection conn) throws SQLException {   
12.        _struct.setAttribute(0, this.losingLEName);   
13.        _struct.setAttribute(1, this.losingLECode);   
14.        return _struct.toDatum(conn, _ORACLE_TYPE_NAME);   
15.    }   
16.    public UkbnovCTCOrder1(String losingLEName, String losingLECode) {   
17.        this();   
18.        this.losingLEName = losingLEName;   
19.        this.losingLECode = losingLECode;   
20.    }   
21.....  
public class UkbnovCTCOrder1 implements ORAData {
    private String losingLEName;
    private String losingLECode;
    public static final String _ORACLE_TYPE_NAME = "BUT_UKBNOV_CTC_ORDER_REC";   
    protected MutableStruct _struct;
    static int[] _sqlType = { OracleTypes.VARCHAR, OracleTypes.VARCHAR };
    static ORADataFactory[] _factory = new ORADataFactory[_sqlType.length];
    public UkbnovCTCOrder1() {
        _struct = new MutableStruct(new Object[_sqlType.length], _sqlType, _factory);
    }
    public Datum toDatum(Connection conn) throws SQLException {
        _struct.setAttribute(0, this.losingLEName);
        _struct.setAttribute(1, this.losingLECode);
        return _struct.toDatum(conn, _ORACLE_TYPE_NAME);
    }
    public UkbnovCTCOrder1(String losingLEName, String losingLECode) {
        this();
        this.losingLEName = losingLEName;
        this.losingLECode = losingLECode;
    }
....调用的时候不需要再做Java bean 到Oracle "AS OBJECT"数据类型的mapping,只需要做数组类型的mapping,如下: 
源码copy to clipboard打印?
01.Connection con = null;   
02.CallableStatement cstmt = null;        
03.try {        
04.    con = OracleConnection.getConn();              
05.    System.out.println(new Date());   
06.    List<UkbnovCTCOrder1> orderList = new ArrayList<UkbnovCTCOrder1>();   
07.    for(int i=0;i<100000;i++){   
08.        orderList.add(new UkbnovCTCOrder1("losingLEName"+i,"losingLECode+"+i));   
09.    }           
10.    ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_TAB", con);               
11.    ARRAY vArray = new ARRAY(tabDesc, con, orderList.toArray());          
12.       
13.    cstmt = con.prepareCall("{call bulkInsertCTDORDER(?)}");        
14.    cstmt.setArray(1, vArray);                  
15.    cstmt.execute();   
16.    con.commit();  
        Connection con = null;
        CallableStatement cstmt = null;     
        try {     
            con = OracleConnection.getConn();           
            System.out.println(new Date());
            List<UkbnovCTCOrder1> orderList = new ArrayList<UkbnovCTCOrder1>();
            for(int i=0;i<100000;i++){
                orderList.add(new UkbnovCTCOrder1("losingLEName"+i,"losingLECode+"+i));
            }        
            ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_TAB", con);            
            ARRAY vArray = new ARRAY(tabDesc, con, orderList.toArray());       
            
            cstmt = con.prepareCall("{call bulkInsertCTDORDER(?)}");     
            cstmt.setArray(1, vArray);               
            cstmt.execute();
            con.commit();上面的示例在插入10万条记录只用了5秒(当然也和这里的表结构字段少有关系). 

原文链接:http://blog.csdn.net/kkdelta/article/details/7226331
分享到:
评论

相关推荐

    oracle 批量插入数据存储过程

    oracle 批量插入数据存储过程。亲测好用。支持 plsql ,toad,等数据库分析软件。主要包括变量的定义,循环及游标的使用等, 亲测好用

    存储过程(循环插入数据)

    总的来说,使用存储过程和FOR LOOP循环在Oracle数据库中批量插入数据是一种高效的方法。然而,考虑到不同工具的兼容性,选择合适的执行环境和调整代码结构都是保证程序顺利运行的关键。对于开发和调试过程,推荐使用...

    C++Oracle存储过程批量插入

    Oracle存储过程是预编译的SQL语句集合,它可以提高执行效率,减少网络通信,并且能够封装复杂的业务逻辑。 首先,我们需要理解C++与Oracle数据库交互的基本原理。通常,这会通过一个名为ODBC(Open Database ...

    C# 传入自定义列表List 到Oracle存储过程

    在.NET开发中,C#与Oracle数据库的交互是常见的任务,特别是当需要处理大量数据时,存储过程可以提供更高的性能和灵活性。本文将详细讲解如何在C#中使用自定义列表(List)作为参数调用Oracle存储过程,以及实现这一...

    oracle数组存储过程批量插入

    在Java示例中,我们还看到了如何为大数据量插入创建Oracle对象类型和数组类型,以及相应的存储过程。这种方式允许我们在单次调用中插入大量记录,显著提高了效率。在处理大量数据时,批量操作比逐条操作更高效,因为...

    Oracle存储过程中使用临时表

    本篇文章将深入探讨如何在Oracle存储过程中使用临时表,包括会话级临时表和事务级临时表。 ### 会话级临时表 会话级临时表(Session-Level Temporary Tables)只在创建它的会话内可见,并且在会话结束时自动删除。...

    oracle存储过程例子

    Oracle存储过程是数据库管理系统Oracle中的一种重要特性,它允许开发者编写包含了一系列SQL和PL/SQL语句的程序单元,用于执行特定的任务。在数据库管理、数据处理和业务逻辑实现方面,存储过程扮演着不可或缺的角色...

    向Oracle数据库插入Clob大段文本解决方法

    - 考虑到性能和效率,对于大量数据的插入或更新操作,可以采用批处理方式,一次执行多条记录的操作,减少数据库交互次数,提高整体性能。 总之,向Oracle数据库插入或更新Clob大段文本是一个涉及SQL语句构建、参数...

    Oracle插入大量数据

    根据给定文件的信息,“Oracle插入大量数据”的主题围绕着几种有效的策略展开,旨在提升Oracle数据库在大数据量场景下的性能表现。 ### 高速存储设备的应用 首先提及的是采用高速的存储设备来提升读写能力。EMC和...

    oracle存储过程使用文档

    ### Oracle存储过程使用知识点 #### 一、存储过程概述 - **定义**:存储过程(Stored Procedure)是在数据库中预编译的一组SQL语句集合,它可以被当作一个单独的对象来调用,只需要指定存储过程的名字及参数(如果...

    oracle存储过程

    Oracle存储过程是数据库管理系统Oracle中的一个重要特性,它允许开发者创建一系列复杂的SQL和PL/SQL语句,形成可重用的代码模块。存储过程可以提高应用程序的性能,减少网络流量,并提供更好的安全性。以下是对...

    Oracle存储过程分页

    1. **提高性能**:存储过程可以在服务器端执行,减少网络传输的数据量。 2. **易于管理**:所有的逻辑都封装在存储过程中,方便后期的修改和维护。 3. **增强安全性**:避免直接暴露SQL语句给前端应用,增加系统的...

    oracle数组存储过程批量插入.pdf

    通过创建一个存储过程,使用数组作为参数来传递大量数据,然后在存储过程中进行批量插入操作。 首先,需要创建一个类型来定义数组,这个类型可以用来存储大量数据。在本文中,创建了一个名为 MSG_ARRAY 的类型,这...

    Oracle存储过程-1

    - **查询性能**:在大量数据的情况下,变长属性可能会导致查询性能下降。 **示例:** 1. **创建表:** ```sql CREATE TABLE test_varchar ( col VARCHAR2(10) ); ``` 创建了一个名为`test_varchar`的表,...

    Oracle存储过程编写及调优

    对于大数据量的表,可以考虑使用分区技术来提高性能。 索引类型包括Unique Scan、Range Scan和Full Scan等,它们分别对应于唯一键查询、范围查询和完整扫描。选择合适的索引类型能有效提高查询效率。需要注意的是,...

    oracle存储过程使用游标对多表操作例子

    对于每个定义的游标,存储过程会遍历结果集,并根据业务逻辑进行相应的数据插入操作。例如,在处理`s_aq`游标时,如果`Ajtype`字段值为“+”,则执行新增库存的操作;反之,则执行其他类型的处理。 ### 结论 本...

    ORACLE数据库中插入大字段数据的解决方法

    如果数据量巨大,可以考虑先将数据插入临时表或利用表分区功能,分批处理,然后再合并到目标表。 6. **调整初始化参数**: 优化数据库参数如`DB_FILE_MULTIBLOCK_READ_COUNT`和`LOB_CACHE_SIZE`,可以提升大字段...

    oracle使用存储过程插入文件至数据库操作方法

    通过上述步骤,我们成功地实现了使用Oracle存储过程将文件插入数据库的功能。这种方法不仅方便了文件的管理和查询,还能够在一定程度上提高系统的整体效率。但在实际应用中还需注意性能优化及安全性的考虑。

    使用oracle存储过程将xml文件数据导入数据库

    这个存储过程接受一个CLOB类型的XML字符串作为参数,通过EXTRACTVALUE函数提取数据,并用INSERT语句将数据插入到`customers`表中。 3. 执行存储过程:现在,你可以调用这个存储过程来导入XML数据。假设有一个名为`...

Global site tag (gtag.js) - Google Analytics