1. 程式人生 > >Oracle儲存過程傳入List引數

    Oracle儲存過程傳入List引數
    --第一步,建立資料庫物件
    CREATE OR REPLACE TYPE param_object is object(
      configId nvarchar2(64),
      evaluateScore number(18,2),
      evaluateLevel nvarchar2(64)
    ); 
    
    
    --第二步,建立資料庫list並且與資料庫物件掛關係
    create type param_array as table of param_object;
    
    
    --第三步,建立儲存過程將list<object>
    create or replace procedure PRO_UPDATE_EVALUATE_SCORE(paramList in param_array,
                                                          result_id out varchar2) is
    begin
      for i in 1 .. paramList.count loop
        update SCM_TEST
           set CONFIGID      = paramList(i).configId,
               EVALUATESCORE = paramList(i).evaluateScore where
               EVALUATELEVEL = paramList(i).evaluateLevel;
               result_id := i;
      end loop;
      commit;
    end PRO_UPDATE_EVALUATE_SCORE;
    
    package com.atguigu.springdata.test;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Types;
    import java.util.ArrayList;
    import java.util.Date;
    import com.sun.org.apache.xerces.internal.impl.dtd.models.DFAContentModel;
    
    import oracle.jdbc.OracleCallableStatement;
    import oracle.sql.ARRAY;
    import oracle.sql.ArrayDescriptor;
    import oracle.sql.STRUCT;
    import oracle.sql.StructDescriptor;
    
    public class Tesst {
    	// 資料庫連線
    	private static final String connectionURL = "jdbc:oracle:thin:@127.0.0.1:1521/oracle11g";
    	private static final String userID = "oracle11g";
    	private static final String userPassword = "oracle11g";
    	private static final String driver_class = "oracle.jdbc.driver.OracleDriver";
    
    	public void runTest() {
    		//組裝需要的引數List<String[]> String[] length 要和資料庫的自定物件PARAM_OBJECT個數一樣
    		String chars = "abcdefghijklmnopqrstuvwxyz";
    		ArrayList list = new ArrayList<>();
    		for(int i=0;i<2000;i++){
    			String c = chars.charAt((int)(Math.random() * 26))+"";
    			String[] values = { i + 1 + "", i + 1 + "",c.toUpperCase()};
    			list.add(values);
    		}
    		   
    		   
    		Connection con = null;
    		OracleCallableStatement stmt = null;
    		try {
    			Class.forName(driver_class).newInstance();
    			con = DriverManager.getConnection(connectionURL, userID,
    					userPassword);
    			
    			ARRAY aArray = getArray(con, "PARAM_OBJECT","PARAM_ARRAY", list,11);
    			
    			System.out.println("開始時間:"+  new Date());
    			stmt = (OracleCallableStatement) con.prepareCall("{call PRO_UPDATE_EVALUATE_SCORE(?,?)}");
    			
    			stmt.setARRAY(1, aArray);
    //			stmt.setArray(1, aArray);
    			stmt.registerOutParameter(2, Types.VARCHAR);
    			
    			stmt.execute();
    			String string = stmt.getString(2);
    			System.out.println("結束時間:"+  new Date());
    			System.out.println("輸出引數:"+string);
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (stmt != null) {
    				try {
    					stmt.close();
    				} catch (SQLException e) {
    					e.printStackTrace();
    				}
    			}
    			if (con != null) {
    				try {
    					con.close();
    				} catch (SQLException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    
    	/**
    	 * 將java陣列轉換成資料庫陣列
    	 * @param con			原生jdbc連結,連結池的連結不行
    	 * @param OracleObj		資料庫自定義物件
    	 * @param Oraclelist	資料庫自定義陣列
    	 * @param objlist		需要的引數
    	 * @param paramNum		自定義物件的個數
    	 * @return	
    	 * @throws Exception
    	 */
    	private ARRAY getArray(Connection con, String OracleObj,
    
    	String Oraclelist, ArrayList objlist,int paramNum) throws Exception {
    
    		ARRAY list = null;
    
    
    		if (objlist != null && objlist.size() > 0) {
    
    			StructDescriptor structdesc = StructDescriptor.createDescriptor(OracleObj,con);
    			
    			STRUCT[] structs = new STRUCT[objlist.size()];
    
    			Object[] result = new Object[0];
    
    			for (int i = 0; i < objlist.size(); i++) {
    				Object[] object = (Object[]) objlist.get(i);
    				String[] str = (String[]) objlist.get(i);
    				
    				result = new Object[paramNum];
    
    				// 陣列大小應和你定義的資料庫物件(AOBJECT)的屬性的個數
    				for(int j=0;j<paramNum;j++){
    					result[j] = str[j];
    				}
    
    				// 將list中元素的資料傳入result陣列 result[1] = new Integer(..); //
    				structs[i] = new STRUCT(structdesc, con, result);
    			}
    
    			ArrayDescriptor desc = ArrayDescriptor.createDescriptor(Oraclelist,
    					con);
    
    			list = new ARRAY(desc, con, structs);
    		}
    
    
    		return list;
    
    	}
    
    	public static void main(String[] args) {
    		Tesst testListToProcedure = new Tesst();
    		testListToProcedure.runTest();
    	}
    
    }

    注:自定義物件裡面的字元必須要使用nvarchar2,不然java程式碼將字串的格式封裝不進去。連結要使用jdbc原生連結(Connection)才能對自定義物件和陣列的轉換,使用連結池轉換不過來。如果誰使用了連線池成功了麻煩您評論下如何操作的,謝謝!