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

时间:2021-10-19 00:44:31
参看了前人的一些资料,自己试了试,有几处改进:
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

http://databird.iteye.com/blog/1070861