java中怎么用存储过程啊?

2025-03-07 08:36:03
推荐回答(4个)
回答1:

对已储存过程的调用是CallableStatement对象所含的内容。这种调用是用一种换码语法来写的,有两种形式:一种形式带结果参,另一种形式不带结果参数。结果参数是一种输出(OUT)参数,是已储存过程的返回值。两种形式都可带有数量可变的输入(IN参数)、输出(OUT参数)或输入和输出(INOUT参数)的参数。问号将用作参数的占位符。在JDBC中调用已储存过程的语法如下所示。注意,方括号表示其间的内容是可选项;方括号本身并非语法的组成部份。 {call过程名[(?,?,...)]} 返回结果参数的过程的语法为: {?=call过程名[(?,?,...)]} 不带参数的已储存过程的语法类似: {call过程名} 通常,创建CallableStatement对象的人应当知道所用的DBMS是支持已储存过程的,并且知道这些过程都是些什么。然而,如果需要检查,多种DatabaseMetaData方法都可以提供这样的信息。例如,如果DBMS支持已储存过程的调用,则supportsStoredProcedures方法将返回true,而getProcedures方法将返回对已储存过程的描述。 CallableStatement继承Statement的方法(它们用于处理一般的SQL语句),还继承了PreparedStatement的方法(它们用于处理IN参)。 CallableStatement中定义的所有方法都用于处理OUT参数或INOUT参数的输出部分:注册OUT参数的JDBC类型(一般SQL类型)、从这些参数中检索结果,或者检查所返回的值是否为JDBCNULL。 JDBC存储过程1、创建CallableStatement对象 CallableStatement对象是用Connection方法prepareCall创建的。下例创建CallableStatement的实例,其中含有对已储存过程getTestData调用。该过程有两个变量,但不含结果参数:CallableStatementc stmt=con.prepareCall("{callgetTestData(?,?)}");其中?占位符为IN、OUT还是INOUT参数,取决于已储存过程getTestData。 JDBC存储过程2、IN和OUT参数 将IN参数传给CallableStatement对象是通过setXXX方法完成的。该方法继承自PreparedStatement。所传入参数的类型决定了所用的setXXX方法(例如,用setFloat来传入float值等)。如果已储存过程返回OUT参数,则在执行CallableStatement对象以前必须先注册每个OUT参数的JDBC类型(这是必需的,因为某些DBMS要求JDBC类型)。注册JDBC类型是用registerOutParameter方法来完成的。语句执行完后,CallableStatement的getXXX方法将取回参数值。正确的getXXX方法是为各参数所注册的JDBC类型所对应的Java类型。换言之,registerOutParameter使用的是JDBC类型(因此它与数据库返回的JDBC类型匹配),而getXXX将之转换为Java类型。 作为示例,下述代码先注册OUT参数,执行由cstmt所调用的已储存过程,然后检索在OUT参数中返回的值。方法getByte从第一个OUT参数中取出一个Java字节,而getBigDecimal从第二个OUT参数中取出一个BigDecimal对象(小数点后面带三位数): CallableStatementc stmt=con.prepareCall("{callgetTestData(?,?)}"); cstmt.registerOutParameter(1,java.sql.Types.TINYINT); cstmt.registerOutParameter(2,java.sql.Types.DECIMAL,3); cstmt.executeQuery(); byte x=cstmt.getByte(1); java.math.BigDecimaln=cstmt.getBigDecimal(2,3); CallableStatement与ResultSet不同,它不提供用增量方式检索大OUT值的特殊机制。JDBC存储过程3、INOUT参数 既支持输入又接受输出的参数(INOUT参数)除了调用registerOutParameter方法外,还要求调用适当的setXXX方法(该方法是从PreparedStatement继承来的)。setXXX方法将参数值设置为输入参数,而registerOutParameter方法将它的JDBC类型注册为输出参数。setXXX方法提供一个Java值,而驱动程序先把这个值转换为JDBC值,然后将它送到数据库中。这种IN值的JDBC类型和提供给registerOutParameter方法的JDBC类型应该相同。然后,要检索输出值,就要用对应的getXXX方法。例如,Java类型为byte的参数应该使用方法setByte来赋输入值。应该给registerOutParameter提供类型为TINYINT的JDBC类型,同时应使用getByte来检索输出值。 下例假设有一个已储存过程reviseTotal,其唯一参数是INOUT参数。方法setByte把此参数设为25,驱动程序将把它作为JDBCTINYINT类型送到数据库中。接着,registerOutParameter将该参数注册为JDBCTINYINT。执行完该已储存过程后,将返回一个新的JDBCTINYINT值。方法getByte将把这个新值作为Javabyte类型检索。 CallableStatementc stmt=con.prepareCall("{callreviseTotal(?)}"); cstmt.setByte(1,25); cstmt.registerOutParameter(1,java.sql.Types.TINYINT); cstmt.executeUpdate(); byte x=cstmt.getByte(1); 1)返回一个结果集(ResultSet)。2)返回一个特定的值。 下面来详细的说明。 1)返回一个结果集(ResultSet),这种类似通常的处理结果集    如果事先就有一个类似如下的procedure CREATE PROCEDURE getShipQuantity @jsid int ASSELECT jf_js_id,SUM(jf_ship_quantity) AS shipqty FROM tjobsheet_finish f WHERE (jf_js_id=@jsid)GROUP BY jf_js_id 那么我们将通过如下的代码来调用   String sql = "{ call getShipQuantity(?) }";Connection con = conn.connection();ResultSet rs = null;BigDecimal shipQuantity = new BigDecimal(0);try{ CallableStatement cs = con.prepareCall(sql); cs.setInt(1,jsoId);//设置输入参数 rs = cs.executeQuery();//返回结果集 if(rs.next()){ shipQuantity = new BigDecimal(rs.getDouble(2)); } logger.debug("shipQuantity --------------------- "+shipQuantity);}catch(Exception e){ logger.debug(e);}2)返回一个特定的值。也就是说,在procedure的定义中已经用output输出参数了。请看下面的proceduercreate procedure getSingleWgt @@singleWgt numeric(8,3) output,@jsnum varchar(11) = '0000-0480'asdeclare @stwgt numeric(8,3)select @stwgt = sum(b.stwgt)from js as ainner join jsactdtl as b on a.jsnum = b.jsnumwhere a.completion = 1 and b.stflag = 22and a.jsnum = @jsnumselect @@singleWgt = (@stwgt/orderedqty) from js where jsnum = @jsnum那么我们将通过如下的代码来调用String sql = "{ call getSingleWgt(?,?) }";Connection con = getSession().connection();//得到connectiontry{ CallableStatement cs = con.prepareCall(sql);//通过它来执行sql cs.registerOutParameter(1,java.sql.Types.FLOAT);//注册输出参数 cs.setString(2,shipment.getJsnum());//指出输入参数 if(cs.execute()){//执行 float output = cs.getFloat(1);//返回值 }}catch(Exception e){logger.debug(e);}

回答2:

创建存储过程 create or replace procedure p_find_emp(i_emp_id in tb_employee.emp_id%type) is v_str_emp_name tb_employee.emp_name%type; begin select emp_name into v_str_emp_name from tb_employee where emp_id=i_emp_id; dbms_output.put_line('该雇员名字叫:'||v_str_emp_name); end p_find_emp; oracle 分页 --创建游标 create or replace package pkg_query is type cur_result_type is ref cursor;--游标的类型 end pkg_query; create or replace procedure p_query_page( str_page_action in varchar2, ---分页动作,可以使上一页:previous_page,下一页:next_page, ----首页:first_page,尾页:last_page,指定页:page_number str_query_table in varchar2, -----需要查询的表,可以以单表或通过连接出来的虚拟表 str_query_condition in varchar2,-----分页的查询条件 str_result_col in varchar2,-----需要输出的字段名 str_order_condition in varchar2,-----查询的排序条件 str_order_style in varchar2,-----排序的风格,升序或降序 i_page_size in out number,-------每页显示的数据条数 i_current_page in out number, ----当前页索引 i_total_record out number,-----当前符合条件的总记录条数 i_total_page out number,-----当前符合条件的总页数 cur_query_result out pkg_query.cur_result_type------查询的结果 ) is v_str_query_sql varchar2(10000):='';-----查询的sql语句 v_i_start_record number(10):=0;----起始记录位置 v_i_end_record number(10):=0;----终止记录的位置begin -------检验指定需要查询的表的参数是否为空 if(str_query_table is null or str_query_table = '') then raise_application_error(-20001,'需要查询的表不能为空'); end if; v_str_query_sql:='select count(*) from '||str_query_table; ------当查询的条件不为空时,将相应的查询条件拼接到sql中 if(str_query_condition is not null and str_query_condition <> '')then v_str_query_sql:=v_str_query_sql||'where '||str_query_condition; end if; -----PL/Sq 动态调用sql execute immediate v_str_query_sql into i_total_record; --------检测每页数据量,如果小于等于零,把每页数据量设为默认值10; if ( i_page_size <= 0 )then i_page_size := 10; end if; ------求当前符合条件的信息的总页数 if mod(i_total_record,i_page_size)=0 then i_total_page := (i_total_record/i_page_size); else i_total_page := trunc(i_total_record/i_page_size)+1; end if; ------根据当前的分页动作转换当前页索引 case str_page_action when 'first_page' then i_current_page := 1; when 'last_page' then i_current_page := i_total_page; when 'previous_page' then i_current_page := i_current_page-1; when 'next_page' then i_current_page := i_current_page+1; when 'page_number' then i_current_page := i_current_page; else i_current_page := 1; end case; ------求起始记录的索引位置和终止记录的索引位置 v_i_start_record := (i_current_page-1)*i_page_size+1; v_i_end_record := i_current_page*i_page_size; -----根据以上结果拼接sql语句。 v_str_query_sql:='select '; if (str_result_col is null or str_result_col='') then raise_application_error(-20002,'需要输出的字段不能为空'); end if; v_str_query_sql:=v_str_query_sql||str_result_col||' from '||str_query_table||' where 1=1 '; ------当查询条件不为空时,把相应的查询条件拼接到sql语句中 if (str_query_condition is not null and str_query_condition <> '') then v_str_query_sql:=v_str_query_sql||str_query_condition; end if; ----当查询的条件不等于空,将查询条件拼接到sql中 if (str_order_condition is not null and str_order_condition <> '') then v_str_query_sql:=v_str_query_sql||' order by '||str_order_condition; if str_order_style is not null and str_order_style <> '' then v_str_query_sql:=v_str_query_sql||' '||str_order_style; end if; end if; v_str_query_sql:='select * from ( select A.*,rownum rn from ( '||v_str_query_sql ||' ) A where rownum <='||v_i_end_record||' ) B where rn >= '||v_i_start_record; dbms_output.put_line(v_str_query_sql); open cur_query_result for v_str_query_sql; end p_query_page; ok 现在看下怎么样调用上面的存储过程package com.softeem.dbc;import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;import oracle.jdbc.driver.OracleTypes;public class DBConnection { private final static String DRIVER_CLASS = "oracle.jdbc.driver.OracleDriver"; private final static String URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; private final static String USER_NAME = "tangzheng"; private final static String PASSWORD = "123456"; public static Connection getconnection() { Connection conn = null;
try {
Class.forName(DRIVER_CLASS);
} catch (ClassNotFoundException e) {
System.out.println("驱动加载失败"); e.printStackTrace();
} try {
conn = DriverManager.getConnection(URL, USER_NAME, PASSWORD);
} catch (SQLException e) {
System.out.println("获取连接失败");
e.printStackTrace();
} return conn; } public PageDTO findOnePage(String pageAction, int pagesize, int currentPage)
throws SQLException { String table = "tb_employee emp";
String queryCondition = "emp.emp_id<15";
String resultcol = "*";
String orderCondition = "emp.emp_id";
String orderstyle = "asc";
Connection conn = getconnection();
PageDTO pageinfo = null;
try { CallableStatement cs = conn
.prepareCall("{call p_query_page(?,?,?,?,?,?,?,?,?,?,?)}");
cs.setString(1, pageAction);
cs.setString(2, table);
cs.setString(3, queryCondition);
cs.setString(4, resultcol);
cs.setString(5, orderCondition);
cs.setString(6, orderstyle);
cs.setInt(7, pagesize);
cs.setInt(8, currentPage); cs.registerOutParameter(7, OracleTypes.INTEGER);
cs.registerOutParameter(8, OracleTypes.INTEGER);
cs.registerOutParameter(9, OracleTypes.INTEGER);
cs.registerOutParameter(10, OracleTypes.INTEGER);
cs.registerOutParameter(11, OracleTypes.CURSOR); cs.execute(); pageinfo = new PageDTO(); pageinfo.setCurrentPage(cs.getInt(7));
pageinfo.setCurrentPage(cs.getInt(8));
pageinfo.setTotalRecord(cs.getInt(9));
pageinfo.setTotalPage(cs.getInt(10)); ResultSet rs = (ResultSet) cs.getObject(11); List employees = new ArrayList(); EmployeeDTO employee = null;
while (rs.next()) { employee = new EmployeeDTO(); employee.setEmpId(rs.getInt("emp_id")); employee.setEmpName(rs.getString("emp_name")); employee.setSex(rs.getString("sex")); employee.setSal(rs.getDouble("sal")); employees.add(employee); }
pageinfo.setResult(employees); } finally { if (conn != null && !conn.isClosed()) { conn.close(); } }
return pageinfo; } public static void main(String[] args) { String pageAction = "nextPage";
int pagesize = 5; int currentpage = 2;
DBConnection db = new DBConnection(); try {
PageDTO pageinfo = db
.findOnePage(pageAction, pagesize, currentpage); List list = pageinfo.getResult(); System.out.println("总页数:" + pageinfo.getCurrentPage());
System.out.println("总记录数:" + pageinfo.getTotalRecord());
for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i).toString());
}
} catch (SQLException e) {
e.printStackTrace();
}
}}

回答3:

我这有个例子,你看看吧 public int gasFeeSave(String customerId,String TNJT_RQGWatchNo,
String TNRD_RQGFCostType,String TNRD_RQGFPayDate,String TNRD_RQGFPayType,
String TNRD_RQGFInvoiceType,String TNRD_RQGFInvoiceNo,String TNJT_RQPriceType,
String TNJT_RQGFFeeAddr,String LateFee,String LateFeeYS,String SurchargeMon,
String TNJT_RQGFPayAmount,String TNJT_RQGCCode,String TNRD_RQDes,
String TNRD_RQOper,String ISFree,String TNJT_RQGCCurrentlyNum)
{
int res=0;
StringBuffer Sql=new StringBuffer();
Connecter conn=new Connecter();
com.grs.util.AutoKey autokey=null;
String keyCode=null;
String TNJT_RQFCode=null;
if("".equals(LateFee)){
LateFee="0";
}
if("".equals(LateFeeYS)){
LateFeeYS="0";
}
if("".equals(SurchargeMon)){
SurchargeMon="0";
}
if("".equals(TNJT_RQGFPayAmount)){
TNJT_RQGFPayAmount="0";
}
try{
autokey=new com.grs.util.AutoKey();
keyCode=autokey.getCode("TNJT_RQGasFee");
TNJT_RQFCode=autokey.getCode("TNJT_RQFines");
sql="{call TNJT_GASFEESAVE_P(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}";
CallableStatement cstmt=conn.conn.prepareCall(sql);
cstmt.setString(1,keyCode);
cstmt.setString(2,TNJT_RQFCode);
cstmt.setString(3,customerId);
cstmt.setString(4,TNJT_RQGWatchNo);
cstmt.setString(5,TNRD_RQGFCostType);
cstmt.setString(6,TNRD_RQGFPayDate);
cstmt.setString(7,TNRD_RQGFPayType);
cstmt.setString(8,TNRD_RQGFInvoiceType);
cstmt.setString(9,TNRD_RQGFInvoiceNo);
cstmt.setString(10,TNJT_RQPriceType);
cstmt.setString(11,TNJT_RQGFFeeAddr);
cstmt.setDouble(12,Double.parseDouble(LateFee));
cstmt.setDouble(13,Double.parseDouble(LateFeeYS));
cstmt.setDouble(14,Double.parseDouble(SurchargeMon));
cstmt.setDouble(15,Double.parseDouble(TNJT_RQGFPayAmount));
cstmt.setString(16,TNJT_RQGCCode);
cstmt.setString(17,TNRD_RQDes);
cstmt.setString(18,TNRD_RQOper);
cstmt.setString(19,ISFree);
cstmt.setInt(20,Integer.parseInt(TNJT_RQGCCurrentlyNum));
cstmt.registerOutParameter(21,java.sql.Types.INTEGER);
cstmt.execute();
res=cstmt.getInt(21);
System.out.println(format.format(date)+"==gasFeeSave==存储过程==="+sql);
}catch(Exception e){
e.printStackTrace();
}finally{
autokey.closeconn();
conn.closeconn();
}
return res;
}

回答4:

CallableStatement