用java调用oracle存储过程总结 [code] 1、存储过程是什么?存储过程是数据库服务器端的一个程序,它有两种类型。用于检索数据的SELECT查询类似,检索到的数据可以以数据集的形式返回给客户。另一种类似于INSERT或DELETE查询,它不返回数据,只执行一个动作。一些服务器允许同一存储过程返回数据并执行动作。 2、存储过程何时需要使用 若服务器定义了存储过程,则应根据需要决定是否使用存储过程。存储过程通常是一些经常需要执行的任务,它们通常是为大量记录而执行的。在服务器上执行存储过程可以提高应用程序的性能。这是因为: .服务器通常具有很强的计算能力和速度。 .避免向客户端下载大量数据,减少网络上的传输量。 例如,假设一个应用程序需要计算一个涉及许多记录的数据。如果不使用存储过程,将这些数据下载到客户端,导致网络流量急剧增加。 不仅如此,客户端可能是一台牙齿老化的电脑,它的操作速度非常慢。重用存储过程后,服务器会快速计算数据,只需将数据传输给客户端,其效率非常明显。 3、存储过程的参数 为了执行服务器上的存储过程,通常需要传输一些参数。这些参数分为四类: 第一种称为输入参数,由客户程序传输到存储过程。 第二种称为输出参数,将结果从存储过程返回到客户程序。 第三种称为输入/输出参数,可以通过客户程序将值传递到存储过程,也可以通过存储过程将结果返回到客户程序。 第四种称为状态参数,将错误信息从存储过程返回到客户程序。 需要注意的是,并非所有服务器都支持上述四种类型的参数,例如,InterBase不支持状态参数。 4、oracle 存储过程的基本语法 1.基本结构 CREATE OR REPLACEPROCEDURE 存储过程名称 ( 参数1 IN NUMBER, 参数2 IN NUMBER ) IS 变量1 INTEGER :=0; 变量2 DATE; BEGIN END 存储过程名称 2.SELECT INTO STATEMENT 将select查询的结果存储在变量中,可以同时存储多个列中的多个变量,必须有一个 记录,否则抛出异常(如果没有记录,抛出NO_DATA_FOUND) 例子: BEGIN SELECT col1,col2 into 变量1,变量2 FROM typestruct where xxx; EXCEPTION WHEN NO_DATA_FOUND THEN xxxx; END; 1:无返回值的存储过程 存储过程如下: 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中调用以下代码:
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){ rs.close(); if(stmt!=null){ stmt.close(); } if(conn!=null){ conn.close(); } } } catch (SQLException ex1) { } } } }
当然,这首先需要建立一个TESTB的表格,其中两个字段(I_ID,I_NAME)。 二:有返回值的存储过程(非列表) 存储过程如下: 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中调用以下代码:
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){ rs.close(); if(stmt!=null){ stmt.close(); } if(conn!=null){ conn.close(); } } } catch (SQLException ex1) { } } } } }
注意,这里的proc.getString(2)中的值2不是任意的,而是对应于存储过程中的out列。如果out在第一位,那就是 proc.getString(1)如果是第三个位置,那就是proc.getString(3)当然也可以同时有多个返回值,也就是多加几个out。 参数了。 三、返回列表 由于oracle存储过程中没有返回值,其所有返回值都被out参数取代,列表也不例外。但由于是集合,一般参数不能使用,必须使用 pagkage.所以要分两部分, 1, 构建程序包。如下: CREATE OR REPLACE PACKAGE TESTPACKAGE AS TYPE Test_CURSOR IS REF CURSOR; end TESTPACKAGE; 二、建立存储过程,存储过程如下: CREATE OR REPLACE PROCEDURE TESTC(p_CURSOR out TESTPACKAGE.Test_CURSOR) IS BEGIN OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB; END TESTC; 可以看到,它将游标(可以理解为指针)作为out 来回值的参数。 在java中调用以下代码:
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){ rs.close(); if(stmt!=null){ stmt.close(); } if(conn!=null){ conn.close(); } } } catch (SQLException ex1) { } } } }
这里需要注意的是,在执行之前,必须将oracle驱动包放入class路径中,否则会报错。 [/code]