Oracle儲存過程傳入List
阿新 • • 發佈:2019-02-17
--第一步,建立資料庫物件 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)才能對自定義物件和陣列的轉換,使用連結池轉換不過來。如果誰使用了連線池成功了麻煩您評論下如何操作的,謝謝!