<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    MDA/MDD/TDD/DDD/DDDDDDD
    posts - 536, comments - 111, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    java調(diào)oracle存儲過程

    Posted on 2009-08-12 11:46 leekiang 閱讀(1415) 評論(2)  編輯  收藏 所屬分類: oraclejdbc、事務(wù)、并發(fā)
    ??????? OracleCallableStatement cst = null;
    ?? ??? ?int oracleId = CharacterSet.ZHS16GBK_CHARSET;
    ?? ??? ?oracle.sql.CharacterSet dbCharset = oracle.sql.CharacterSet.make(oracleId);
    ?? ??? ??? ?cst = (OracleCallableStatement) conn
    ?? ??? ??? ??? ??? ?.prepareCall("begin ?:= pkg_test.f_getList(?); end;");
    //String sql = "{?=call PckgStudSltCourse.addStudPreSltCourse(?,?,?,?)}";也可以這樣寫
    //sql="{call sp(?,?,?,?,?)}";//如果無返回值
    ?? ??? ??? ?cst.registerOutParameter(1, OracleTypes.ARRAY, "T_ARRAY");//第一個問號表示返回結(jié)果
    ?? ??? ??? ?cst.setString(2, userid);//第二個問號
    ?? ??? ??? ?cst.executeUpdate();//哪怕是個查詢也用executeUpdate

    ?? ??? ??? ?oracle.sql.ARRAY simpleArray = cst.getARRAY(1);//從statement獲取,而不是rs
    ?? ??? ??? ?String[] values = (String[]) simpleArray.getArray();
    ?? ??? ??? ?for (int i = 0; i < values.length; i++) {
    ?? ??? ??? ??? ?oracle.sql.CHAR out_value = new oracle.sql.CHAR(values[i],dbCharset);
    ?? ??? ??? ??? ?System.out.println(out_value.stringValue());
    ?? ??? ??? ?}
    ?? ??? ??? ?
    注意:在new oracle.sql.CHAR處,可能會報
    java.lang.NoClassDefFoundError: oracle/gss/util/NLSError
    ?? ?at oracle.sql.CharacterSetUnknown.failCharsetUnknown(CharacterSetFactoryThin.java:178)
    ?? ?at oracle.sql.CharacterSetUnknown.convert(CharacterSetFactoryThin.java:145)
    ?? ?at oracle.sql.CHAR.(CHAR.java:147)
    ?? ?即missing some jar file in runtime environment
    ?? ?原因是weblogic沒有加載web應(yīng)用下的classes12.jar,而是加載了weblogic81\server\lib里的ojdbc14.jar,
    ?? ?而ojdbc14.jar里沒有oracle.gss.util.NLSError。
    ?? ?修改classpath先加載classes12.jar,打印出來的是亂碼,只出現(xiàn)亂碼,這次沒有出現(xiàn)類似這樣的異常java.sql.SQLException:?? Non?? supported?? character?? set:?? oracle-character-set-850? 。
    ?? ?還需要修改classpath先加載nls_charset12.jar;(必須這樣,光放在web應(yīng)用的lib下或光放在weblogic81\server\lib都
    ?? ?不行,jar包放置或加載的這三種方式是有區(qū)別的)
    問題:如果使用的是ojdbc.jar,我覺得可能就不要nls_charset12.jar了,并且不需要new oracle.sql.CHAR(values[i],dbCharset)來轉(zhuǎn)換
    ?? ?
    http://topic.csdn.net/t/20051110/17/4385336.html
    ?? ?類是通過類加載器classloader載入的。 ?
    ? 缺省情況下web容器遵循java的標(biāo)準(zhǔn)標(biāo)準(zhǔn)類載入機制?? --?? 由現(xiàn)載入父加載器level的類。 ?
    ? weblogic的web容器的classloader繼承自ejb容器的classloader,ejb容器的classloader又繼承自 application?? classloader--該loader負(fù)責(zé)加載classpath下面的類,所以缺省情況下classpath下面的類會被優(yōu)先載入,即使相同的類存在于web應(yīng)用的lib目錄。 ?
    ? 可以通過配置文件來修改這種加載順序,使得lib目錄中的類得到優(yōu)先調(diào)用,在weblogic?? 8.1中,方法是在weblogic.xml中加入下面的代碼段: ?
    ? <container-descriptor> ?
    ? <prefer-web-inf-classes>true</prefer-web-inf-classes> ?
    ? </container-descriptor>? ?
    ? weblogic?? 的加載順序就是weblogic?? classpath優(yōu)先?
    ?
    ?
    ? 一下見http://www.javaeye.com/topic/21141
    ? ClassNotFoundException發(fā)生在裝入階段。
    當(dāng)應(yīng)用程序試圖通過類的字符串名稱,使用常規(guī)的三種方法裝入類,但卻找不到指定名稱的類定義時就拋出該異常。

    NoClassDefFoundError: 當(dāng)目前執(zhí)行的類已經(jīng)編譯,但是找不到它的定義時

    也就是說你如果編譯了一個類B,在類A中調(diào)用,編譯完成以后,你又刪除掉B,運行A的時候那么就會出現(xiàn)這個錯誤
    當(dāng)你使用字符串去轉(zhuǎn)換類,也就是嘗試使用Class.forName等方法去獲得一個類的時候,如果這個類不存在,就會拋出ClassNotFoundException。
    ?? 而你編譯的類無錯,但是在運行時刻,缺乏某些必須的類時,就是拋出NoClassDefFoundError。這種情況最常見就是你在編譯時,在classpath下有這個類,但是在運行時,你的classpath缺少這個類。
    ? ?
    ? 加載時從外存儲器找不到需要的class就出現(xiàn)ClassNotFoundException
    ? 連接時從內(nèi)存找不到需要的class就出現(xiàn)NoClassDefFoundError
    ? 問題:加載和連接的區(qū)別

    創(chuàng)建測試用表

    CREATETABLE T_TEST(
    I_ID
    NVARCHAR(20),
    I_NAME
    NVARCHAR(20)
    )

    一:無返回值的存儲過程

    1、建立存儲過程
    CREATE OR REPLACE PROCEDURE TESTA(PARA1 IN VARCHAR2,PARA2 IN VARCHAR2) AS
    BEGIN
    ?? INSERT INTO T_TEST (I_ID,I_NAME) VALUES (PARA1, PARA2);
    END TESTA;

    2、相應(yīng)的JAVA程序
    import java.sql.*;
    import java.io.OutputStream;
    import java.io.Writer;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import oracle.jdbc.driver.*;
    public class TestProcedureOne {
    ??? public TestProcedureOne() {
    ????? }
    ????? public static void main(String[] args ){
    ??????? String driver = "oracle.jdbc.driver.OracleDriver";
    ??????? String strUrl = "jdbc:oracle:thin:@192.168.10.216:1521:ctbu";
    ??????? Statement stmt = null;
    ??????? ResultSet rs = null;
    ??????? Connection conn = null;
    ??????? CallableStatement cstmt = null;
    ??????? try {
    ????????? Class.forName(driver);
    ????????? conn = DriverManager.getConnection(strUrl, "dbname", "password");
    ????????? CallableStatement proc = null;
    ????????? proc = conn.prepareCall("{ call dbname.TESTA(?,?) }");
    ????????? proc.setString(1, "100");
    ????????? proc.setString(2, "TestOne");
    ????????? proc.execute();
    ??????? }
    ??????? catch (SQLException ex2) {
    ????????? ex2.printStackTrace();
    ??????? }
    ??????? catch (Exception ex2) {
    ????????? ex2.printStackTrace();
    ??????? }
    ??????? finally{
    ????????? try {
    ??????????? if(rs != null){
    ????????????? rs.close();
    ????????????? if(stmt!=null){
    ??????????????? stmt.close();
    ????????????? }
    ????????????? if(conn!=null){
    ??????????????? conn.close();
    ????????????? }
    ??????????? }
    ????????? }
    ????????? catch (SQLException ex1) {
    ????????? }
    ??????? }
    ????? }
    ??? }

    二:有返回值的存儲過程(非列表)

    1、存儲過程為
    CREATE OR REPLACE PROCEDURE TESTB(PARA1 IN VARCHAR2,PARA2 OUT VARCHAR2) AS
    BEGIN
    ?? SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1;
    END TESTB;

    2、JAVA代碼
    public class TestProcedureTWO {
    public TestProcedureTWO() {
    }
    public static void main(String[] args ){
    ??? String driver = "oracle.jdbc.driver.OracleDriver";
    ??? String strUrl = "jdbc:oracle:thin:@192.168.10.216:1521:ctbu";
    ??? Statement stmt = null;
    ??? ResultSet rs = null;
    ??? Connection conn = null;
    ??? try {
    ????? Class.forName(driver);
    ????? conn = DriverManager.getConnection(strUrl, "dbname", "password");
    ????? CallableStatement proc = null;
    ????? proc = conn.prepareCall("{ call HYQ.TESTB(?,?) }");
    ????? proc.setString(1, "100");
    ????? proc.registerOutParameter(2, Types.VARCHAR);
    ????? proc.execute();
    ????? String testPrint = proc.getString(2);
    ????? System.out.println("=testPrint=is="+testPrint);
    ??? }
    ??? catch (SQLException ex2) {
    ????? ex2.printStackTrace();
    ??? }
    ??? catch (Exception ex2) {
    ????? ex2.printStackTrace();
    ??? }
    ??? finally{
    ????? try {
    ??????? if(rs != null){
    ????????? rs.close();
    ????????? if(stmt!=null){
    ??????????? stmt.close();
    ????????? }
    ????????? if(conn!=null){
    ??????????? conn.close();
    ????????? }
    ??????? }
    ????? }
    ????? catch (SQLException ex1) {
    ????? }
    ??? }
    }
    }
    }
    注意,這里的proc.getString(2)中的數(shù)值2并非任意的,而是和存儲過程中的out列對應(yīng)的,如果out是在第一個位置,那就是 proc.getString(1),如果是第三個位置,就是proc.getString(3),當(dāng)然也可以同時有多個返回值,那就是再多加幾個out 參數(shù)了。

    三:返回列表
    由于oracle存儲過程沒有返回值,它的所有返回值都是通過out參數(shù)來替代的,列表同樣也不例外,但由于是集合,所以不能用一般的參數(shù),必須要用pagkage了.所以要分兩部分。
    1、在SQL*PLUS中建一個程序包

    CREATE OR REPLACE PACKAGE TESTPACKAGE AS
    TYPE Test_CURSOR IS REF CURSOR;
    procedure TESTC(cur_ref out Test_CURSOR);
    end TESTPACKAGE;

    建立存儲過程,存儲過程為:
    create or replace package body TESTPACKAGE as
    procedure TESTC(cur_ref out Test_CURSOR) is
    begin??
    OPEN cur_ref FOR SELECT * FROM T_TEST;
    end TESTC;
    END TESTPACKAGE;
    可以看到,它是把游標(biāo)(可以理解為一個指針),作為一個out 參數(shù)來返回值的。
    JAVA程序如下:

    import java.sql.*;
    import java.io.OutputStream;
    import java.io.Writer;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import oracle.jdbc.driver.*;

    public class TestProcedureOne {
    ??? public TestProcedureOne() {
    ????? }
    ????? public static void main(String[] args ){
    ??????? String driver = "oracle.jdbc.driver.OracleDriver";
    ??????? String strUrl = "jdbc:oracle:thin:@192.168.10.216:1521:ctbu";
    ??????? Statement stmt = null;
    ??????? ResultSet rs = null;
    ??????? Connection conn = null;
    ??????? CallableStatement cstmt = null;
    ??????? try {
    ????????? Class.forName(driver);
    ????????? conn = DriverManager.getConnection(strUrl,"databasename" "password");
    ????????? CallableStatement proc = null;
    ????????? proc = conn.prepareCall("{ call cqsb.TESTA(?,?) }");
    ????????? proc.setString(1, "100");
    ????????? proc.setString(2, "TestOne");
    ????????? proc.execute();
    ??????? }
    ??????? catch (SQLException ex2) {
    ????????? ex2.printStackTrace();
    ??????? }
    ??????? catch (Exception ex2) {
    ????????? ex2.printStackTrace();
    ??????? }
    ??????? finally{
    ????????? try {
    ??????????? if(rs != null){
    ????????????? rs.close();
    ????????????? if(stmt!=null){
    ??????????????? stmt.close();
    ????????????? }
    ????????????? if(conn!=null){
    ??????????????? conn.close();
    ????????????? }
    ??????????? }
    ????????? }
    ????????? catch (SQLException ex1) {
    ????????? }
    ??????? }
    ????? }
    ??? }

    特別注意:
    1、在執(zhí)行前一定要先把oracle的驅(qū)動包放到class路徑里。
    2、Toad在我建立存儲過程中搞了很多莫名的錯誤,多數(shù)是沒有創(chuàng)建成功而不報錯,
    或者是創(chuàng)建有誤而不提示,應(yīng)當(dāng)引起重視。所以最好還是在SQL*PLUS玩這些。
    3、在SQL*PLUS中的換行是無效的,要換行的時候一定要空格結(jié)尾,特別是你直接復(fù)制代碼的時候!



    評論

    # re: java調(diào)oracle存儲過程  回復(fù)  更多評論   

    2010-01-12 19:18 by leekiang
    //如果java代碼是utf-8編碼,則不需要ZHS16GBK_CHARSET和new oracle.sql.CHAR(values[i],dbCharset)了:
    如下:
    ARRAY a= cst.getARRAY(1);
    Datum[] data = a.getOracleArray();
    for (int i = 0; i < data.length; i++) {
    System.out.println(
    new String(data[i].shareBytes()));
    }

    # re: java調(diào)oracle存儲過程  回復(fù)  更多評論   

    2010-01-12 19:24 by leekiang

    http://zhouyq.javaeye.com/blog/240440
    主站蜘蛛池模板: 中文字幕av无码无卡免费| 亚洲国产成人久久精品99| 色婷婷六月亚洲综合香蕉| 在线观看亚洲天天一三视| 久9热免费精品视频在线观看| 精品亚洲AV无码一区二区三区| 免费国产综合视频在线看 | 久久综合给合久久国产免费 | 亚洲毛片αv无线播放一区| 亚洲免费网站在线观看| 免费精品国自产拍在线播放| 亚洲AV无码久久精品狠狠爱浪潮| 日韩欧美一区二区三区免费观看| 一级毛片aa高清免费观看| 亚洲国产视频一区| 久久久久亚洲精品无码网址| 国产精品免费观看| xxxxxx日本处大片免费看| 亚洲免费福利视频| 亚洲伊人久久精品影院| 免费看大美女大黄大色| 99re6在线视频精品免费下载 | 在线观看免费黄网站| 亚洲精品国产第一综合99久久| 亚洲情综合五月天| 免费精品国产自产拍观看| 69xx免费观看视频| a在线视频免费观看| 最新亚洲人成无码网站| 亚洲国产中文在线二区三区免| 亚洲精品无码久久一线| 四虎永久精品免费观看| 国产精品无码免费播放| 18禁止看的免费污网站| 在线观看免费视频网站色| 搜日本一区二区三区免费高清视频| 麻豆狠色伊人亚洲综合网站| 亚洲视频手机在线| 亚洲va无码专区国产乱码| 国产精品亚洲二区在线观看| 国产无遮挡吃胸膜奶免费看视频|