??????? 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ù)制代碼的時候!