qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問 http://qaseven.github.io/

          用java調(diào)用oracle存儲(chǔ)過程總結(jié)

           1、什么是存儲(chǔ)過程。存儲(chǔ)過程是數(shù)據(jù)庫(kù)服務(wù)器端的一段程序,它有兩種類型。一種類似于SELECT查詢,用于檢索數(shù)據(jù),檢索到的數(shù)據(jù)能夠以數(shù)據(jù)集的形式返回給客戶。另一種類似于INSERT或DELETE查詢,它不返回?cái)?shù)據(jù),只是執(zhí)行一個(gè)動(dòng)作。有的服務(wù)器允許同一個(gè)存儲(chǔ)過程既可以返回?cái)?shù)據(jù)又可以執(zhí)行動(dòng)作。
            2、什么時(shí)候需要用存儲(chǔ)過程
            如果服務(wù)器定義了存儲(chǔ)過程,應(yīng)當(dāng)根據(jù)需要決定是否要用存儲(chǔ)過程。存儲(chǔ)過程通常是一些經(jīng)常要執(zhí)行的任務(wù),這些任務(wù)往往是針對(duì)大量的記錄而進(jìn)行的。在服務(wù)器上執(zhí)行存儲(chǔ)過程,可以改善應(yīng)用程序的性能。這是因?yàn)椋?/div>
            .服務(wù)器往往具有強(qiáng)大的計(jì)算能力和速度。
            .避免把大量的數(shù)據(jù)下載到客戶端,減少網(wǎng)絡(luò)上的傳輸量。
            例如,假設(shè)一個(gè)應(yīng)用程序需要計(jì)算一個(gè)數(shù)據(jù),這個(gè)數(shù)據(jù)需要涉及到許多記錄。如果不使用存儲(chǔ)過程的話,把這些數(shù)據(jù)下載到客戶端,導(dǎo)致網(wǎng)絡(luò)上的流量劇增。
            不僅如此,客戶端可能是一臺(tái)老掉牙的計(jì)算機(jī),它的運(yùn)算速度很慢。而改用存儲(chǔ)過程后,服務(wù)器會(huì)很快地把數(shù)據(jù)計(jì)算出來(lái),并且只需傳遞一個(gè)數(shù)據(jù)給客戶端,其效率之高是非常明顯的。
            3、存儲(chǔ)過程的參數(shù)
            要執(zhí)行服務(wù)器上的存儲(chǔ)過程,往往要傳遞一些參數(shù)。這些參數(shù)分為四種類型:
            第一種稱為輸入?yún)?shù),由客戶程序向存儲(chǔ)過程傳遞值。
            第二種稱為輸出參數(shù),由存儲(chǔ)過程向客戶程序返回結(jié)果。
            第三種稱為輸入/輸出參數(shù),既可以由客戶程序向存儲(chǔ)過程傳遞值,也可以由存儲(chǔ)過程向客戶程序返回結(jié)果。
            第四種稱為狀態(tài)參數(shù),由存儲(chǔ)過程向客戶程序返回錯(cuò)誤信息。
            要說(shuō)明的是,并不是所有的服務(wù)器都支持上述四種類型的參數(shù),例如,InterBase就不支持狀態(tài)參數(shù)。
            4、oracle 存儲(chǔ)過程的基本語(yǔ)法
            1.基本結(jié)構(gòu)
            CREATE OR REPLACEPROCEDURE 存儲(chǔ)過程名字
            (
            參數(shù)1 IN NUMBER,
            參數(shù)2 IN NUMBER
            ) IS
            變量1 INTEGER :=0;
            變量2 DATE;
            BEGIN
            END 存儲(chǔ)過程名字
            2.SELECT INTO STATEMENT
            將select查詢的結(jié)果存入到變量中,可以同時(shí)將多個(gè)列存儲(chǔ)多個(gè)變量中,必須有一條
            記錄,否則拋出異常(如果沒有記錄拋出NO_DATA_FOUND)
            例子:
            BEGIN
            SELECT col1,col2 into 變量1,變量2 FROM typestruct where xxx;
            EXCEPTION
            WHEN NO_DATA_FOUND THEN
            xxxx;
            END;
            一:無(wú)返回值的存儲(chǔ)過程
            存儲(chǔ)過程為:
            CREATE OR REPLACE PROCEDURE TESTA(PARA1 IN VARCHAR2,PARA2 IN VARCHAR2) AS
            BEGIN
            INSERT INTO HYQ.B_ID (I_ID,I_NAME) S (PARA1, PARA2);
            END TESTA;

          然后呢,在java里調(diào)用時(shí)就用下面的代碼:
          package com.hyq.src;
          import java.sql.*;
          import java.sql.ResultSet;
          public class TestProcedureOne {
          public TestProcedureOne() {
          }
          public static void main(String[] args ){
          String driver = "oracle.jdbc.driver.OracleDriver";
          String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521: hyq ";
          Statement stmt = null;
          ResultSet rs = null;
          Connection conn = null;
          CallableStatement cstmt = null;
          try {
          Class.forName(driver);
          conn = DriverManager.getConnection(strUrl, " hyq ", " hyq ");
          CallableStatement proc = null;
          proc = conn.prepareCall("{ call HYQ.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) {
          }
          }
          }
          }
            當(dāng)然了,這就先要求要建張表TESTTB,里面兩個(gè)字段(I_ID,I_NAME)。
            二:有返回值的存儲(chǔ)過程(非列表)
            存儲(chǔ)過程為:
            CREATE OR REPLACE PROCEDURE TESTB(PARA1 IN VARCHAR2,PARA2 OUT VARCHAR2) AS
            BEGIN
            SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1;
            END TESTB;
           在java里調(diào)用時(shí)就用下面的代碼:
          package com.hyq.src;
          public class TestProcedureTWO {
          public TestProcedureTWO() {
          }
          public static void main(String[] args ){
          String driver = "oracle.jdbc.driver.OracleDriver";
          String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";
          Statement stmt = null;
          ResultSet rs = null;
          Connection conn = null;
          try {
          Class.forName(driver);
          conn = DriverManager.getConnection(strUrl, " hyq ", " hyq ");
          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并非任意的,而是和存儲(chǔ)過程中的out列對(duì)應(yīng)的,如果out是在第一個(gè)位置,那就是proc.getString(1),如果是第三個(gè)位置,就是proc.getString(3),當(dāng)然也可以同時(shí)有多個(gè)返回值,那就是再多加幾個(gè)out參數(shù)了。
            三:返回列表
            由于oracle存儲(chǔ)過程沒有返回值,它的所有返回值都是通過out參數(shù)來(lái)替代的,列表同樣也不例外,但由于是集合,所以不能用一般的參數(shù),必須要用pagkage了.所以要分兩部分,
            1, 建一個(gè)程序包。如下:
            CREATE OR REPLACE PACKAGE TESTPACKAGE  AS
            TYPE Test_CURSOR IS REF CURSOR;
            end TESTPACKAGE;
            2,建立存儲(chǔ)過程,存儲(chǔ)過程為:
            CREATE OR REPLACE PROCEDURE TESTC(p_CURSOR out TESTPACKAGE.Test_CURSOR) IS
            BEGIN
            OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB;
            END TESTC;
            可以看到,它是把游標(biāo)(可以理解為一個(gè)指針),作為一個(gè)out 參數(shù)來(lái)返回值的。
            在java里調(diào)用時(shí)就用下面的代碼:
          package com.hyq.src;
          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 TestProcedureTHREE {
          public TestProcedureTHREE() {
          }
          public static void main(String[] args ){
          String driver = "oracle.jdbc.driver.OracleDriver";
          String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";
          Statement stmt = null;
          ResultSet rs = null;
          Connection conn = null;
          try {
          Class.forName(driver);
          conn = DriverManager.getConnection(strUrl, "hyq", "hyq");
          CallableStatement proc = null;
          proc = conn.prepareCall("{ call hyq.testc(?) }");
          proc.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);
          proc.execute();
          rs = (ResultSet)proc.getObject(1);
          while(rs.next())
          {
          System.out.println("<tr><td>" + rs.getString(1) + "</td><td>"+rs.getString(2)+"</td></tr>");
          }
          }
          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) {
          }
          }
          }
          }
            在這里要注意,在執(zhí)行前一定要先把oracle的驅(qū)動(dòng)包放到class路徑里,否則會(huì)報(bào)錯(cuò)。

          posted on 2014-05-28 09:48 順其自然EVO 閱讀(185) 評(píng)論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫(kù)

          <2014年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          • 隨筆 - 3936
          • 文章 - 404
          • 評(píng)論 - 179
          • 引用 - 0

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 环江| 筠连县| 积石山| 民权县| 万盛区| 沅江市| 桂平市| 铜山县| 广元市| 烟台市| 汉中市| 辽阳市| 扶沟县| 河津市| 天台县| 锦州市| 甘孜县| 嘉义市| 满城县| 澎湖县| 南郑县| 双桥区| 安溪县| 嘉义市| 金昌市| 孝昌县| 荣成市| 乌拉特前旗| 屏南县| 大城县| 大足县| 乌审旗| 灵山县| 景宁| 襄城县| 白朗县| 闽侯县| 湘乡市| 罗平县| 滦平县| 大兴区|