JAVA调用ORACLE带数组输入参数和返回游标结果集的存储过程

参看了前人的一些资料,自己试了试,有几处改进:
1.关于字符集:11g的jdbc驱动叫orai18n.jar,之前是nls_charset.jar/classes12.jar
2.ArrayDescriptor:java传入oracle的数组需要处理一下
3.oracle.jdbc.OracleTypes.CURSOR:java获得oracle的游标。

package TEST;
import java.sql.*;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
public class test_array {
static Connection connMyDB = null;
public static Connection connDB() {
Statement stmt;
ResultSet rs;
PreparedStatement pstmt;
String driver = "oracle.jdbc.driver.OracleDriver";
String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:wydb";
try {
Class.forName(driver);
connMyDB = DriverManager.getConnection(strUrl, "dev", "dev");
} catch (SQLException ex) {
Logger.getLogger(test_array.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(test_array.class.getName()).log(Level.SEVERE, null, ex);
}
return connMyDB;
}
public static void main(String args[]) {
ArrayList arrList = new ArrayList();
try {
CallableStatement proc = connDB().prepareCall("{ call p_web_sql_kpi(?,?,?,?,?,?,?,?,?,?) }"); //调用存储过程
//不一样的地方,获得上面创建的自定义的类型,注意大小写
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("VARRAY_LIST", connMyDB);
List list = new ArrayList();
list.add("TRAFFIC_PD");
list.add("TRAFFIC_TCH");
list.add("REQ_TBF_DL_GPRS");
//把list中的元素转换成自定义的类型
ARRAY array = new ARRAY(descriptor, connMyDB, list.toArray());
/*重要!这里输出的全是“???”试验NLS
备注:如果在入库的过程中发现字符串的值没有入进去,
请检查有没有加载该类库orai18n.jar(11g之前:nls_charset12.jar)*/
String[] tem = (String[]) array.getArray();
for (String str : tem) {
System.out.println(str);
}
//设置参数, 和普通的一样
proc.setString(1, "LC");
proc.setString(2, "201104自行车赛");
proc.setString(3, "2011-05-31");
proc.setString(4, "2011-06-01");
proc.setInt(5, 9);
proc.setInt(6, 11);
proc.setArray(7, array);
proc.setInt(8, 1);
proc.setInt(9, 10);
proc.registerOutParameter(10, oracle.jdbc.OracleTypes.CURSOR);
proc.execute();
ResultSet rs = (ResultSet) proc.getObject(10);
int cols = rs.getMetaData().getColumnCount();//width=how many cols
while (rs.next()) {
for (int i = 1; i <= cols; i++) {
System.out.print(rs.getString(i));
if (i != cols) {
System.out.print(" / ");//列之间的间隔符,最后1列不需要
}
}
System.out.println();
}
rs.close();
proc.close();
} catch (Exception ex) {
ex.getMessage();
} finally {
try {
connMyDB.close();
} catch (SQLException ex) {
Logger.getLogger(test_array.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}


我们的数据库字符编码一般选zhs16GBK用以支持中文,字符集不对,把nls_charset12.jar(11g以前的)添加到classpath里面去,jdbc的lib下面。
对于Oracle 11g R2+WINDOWS SERVER 2003:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Oracle Database 11g Release 2 JDBC Drivers 的解释:
ojdbc5.jar 用于 JDK 1.5 的类。它包含 JDBC 驱动程序类,但不包含在 Oracle Object 和 Collection 类型中支持 NLS 的类。
ojdbc6.jar 用于 JDK 1.6 的类。它包含 JDBC 驱动程序类,但不包含在 Oracle Object 和 Collection 类型中支持 NLS 的类。
orai18n.jar 用于 JDK 1.5 和 1.6 的 NLS 类。它包含在 Oracle Object 和 Collection 类型中支持 NLS 的类。
该文件代替旧的nls_charset.jar/classes12.jar 文件。
orai18n.jar - NLS classes for use with JDK 1.5, and 1.6. It contains classes for NLS support in Oracle Object and Collection types. This jar file replaces the old nls_charset jar/zip files.
下载网址,请用迅雷,否则需要注册的用户名和密码:
http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html


sqlplus的command窗口下:
var v_result refcursor
declare
v_kpi varray_list;
begin
p_web_sql_kpi(v_usr => '星星星',
v_ciset => '201104自行车赛',
v_date_begin => '2011-05-31',
v_date_end => '2011-06-01',
v_time_begin => '9',
v_time_end => '11',
v_kpi => varray_list('TRAFFIC_TCH',
'TRAFFIC_PD',
'REQ_TBF_DL_GPRS'),
v_startidx => 1,
v_endidx => 10,
v_result => :v_result);
end;
/
print v_result

你可能感兴趣的:(Oracle,Java,JDBC,SQL,SQL,Server)