日期:2014-05-16 浏览次数:20547 次
用JDBC给存储过程传递数组类型的参数 收藏 
A . 嵌套表 
1. 声明数组类型 
       create or replace type tab_array is table of varchar2(38);暂时不要在包中声明该类型 
2. 创建存储过程 
         -- 该例子存储过程是在包中创建的,包名 arraydemo 
         procedure testArray(resNumber in tab_array,procResult out tab_array) is 
         begin 
             procResult := new tab_array(); 
             for i in 1..resNumber.Count loop 
                procResult.EXTEND; 
                procResult(i) := resNumber(i) || 'lucifer' || i; 
             end loop; 
         end; 
3. Java调用代码 
    //必须使用Oracle的连接和Statement,使用了连接池的必须通过一些方法获取原始的连接 
    OracleConnection conn = null; 
    OracleCallableStatement stmt = null; 
    String[] param = { "1001", "1002", "1006" }; 
    stmt =(转换类型) conn.prepareCall("{call arraydemo.testArray(?,?)}"); 
    // 类型名必须大写 
    ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("TAB_ARRAY", conn); 
    stmt.setARRAY(1, new ARRAY(descriptor,conn,param)); 
    stmt.registerOutParameter(2, OracleTypes.ARRAY, "TAB_ARRAY"); 
    stmt.execute(); 
    ARRAY array = stmt.getARRAY(2); 
    Datum[] data = array.getOracleArray(); 
    for (int i = 0; i < data.length; i++) { 
        System.out.println(i + " : " + new String(data.shareBytes())); 
    } 
4 . 注意的问题及尚未解决的问题 
    抛出:Non supported character set: oracle-character-set-852 异常---解决:添加 nls_charset12.jar 到classpath,该包在oracle/ora92/jdbc/lib目录下 
    待解决问题: 
    a) 如何调用在包声明的自定义类型 
    b) 比较不同声明类型的优缺点,及使用场合 
    嵌套表其它应用:http://zhouwf0726.itpub.net/post/9689/212253 
例程: 
import java.sql.*; 
public class DBDeclareTest{ 
private Connection con = null;// 数据库连接 
private java.sql.CallableStatement cs = null;//执行存储过程的接口 
private int key; 
private String name; 
//在构造函数中构造连接 
public DBDeclareTest(){ 
try { 
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); 
con = DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=pubs","sa",""); 
System.out.println ("con ok"); 
    } 
    catch (Exception ex) { 
    ex.printStackTrace(); 
    } 
} 
//调用无返回值的存储过程 
public void getOK1(){ 
try { 
String sql="{call pro_mypro1(?,?)}"; 
cs = con.prepareCall(sql); 
cs.setInt(1,key); 
cs.setString(2,name); 
cs.executeUpdate(); 
System.out.println ("执行成功,可以休息了。。。。"); 
cs.close(); 
con.close(); 
    } 
    catch (Exception ex) { 
    ex.printStackTrace(); 
    } 
} 
//调用有返回值的存储过程 
public void getOK2(){ 
try { 
String sql = "{call pro_mypro2(?,?)}"; 
cs = con.prepareCall(sql); 
//设置output外部传参 
cs.registerOutParameter(1,java.sql.Types.BIT); 
cs.setString(2,name); 
cs.execute(); 
//获得output外部传参的值 
int numOut = cs.getInt(1); 
if(numOut ==1){ 
System.out.println ("数据表存在"); 
}else{ 
System.out.println ("数据表不存在!!!"); 
} 
cs.close(); 
con.close(); 
    } 
    catch (Exception ex) { 
    ex.printStackTrace(); 
    } 
} 
//返回结果集的存储过程 
public void getOK3(){ 
try { 
String sql = "{call pro_mypro3(?,?)}"; 
cs = con.prepareCall(sql); 
//设置output外部传参 
cs.registerOutParameter(1,java.sql.Types.BIT); 
cs.setString(2,name); 
boolean flag = cs.execute(); 
System.out.println (flag); 
if(flag){ 
System.out.println ("OKOKOKO"); 
ResultSet rs = cs.getResultSet(); 
ResultSetMetaData rsmd =rs.getMetaData(); 
     int numberOfColumns = rsmd.getColumnCount(); 
while(rs.next()){ 
for(int i=0;i<numberOfColumns;i++) 
{ 
System.out.println (rsmd.getColumnName(i)+"  "); 
System.out.println (rs.getObject(i)+"  "); 
} 
} 
}else 
{ 
System.out.println ("表名不存在:"+cs.getBoolean(1)); 
} 
cs.close(); 
con.close(); 
    } 
    catch (Exception ex) { 
    ex.printStackTrace(); 
    } 
} 
public