什么是存储过程、存储过程语法结构
存储过程是被命名的PL/SQL块,存储于数据库中,是数据库对象的一种。应用程序可以调用存储过程,执行相应的逻辑。
存储过程与存储函数都可以封装一定的业务逻辑并返回结果,存在区别如下:
1、存储函数中有返回值,且必须返回;而存储过程没有返回值,可以通过传出参数返回多个值。
2、存储函数可以在select语句中直接使用,而存储过程不能。过程多数是被应用程序所调用。
3、存储函数一般都是封装一个查询结果,而存储过程一般都封装一段事务代码。
创建或修改存储过程的语法如下:
CREATE [ OR REPLACE ] PROCEDURE 存储过程名称 (参数名 类型, 参数名 类型, 参数名 类型) IS|AS 变量声明部分; BEGIN 逻辑部分 [EXCEPTION 异常处理部分] END; |
参数只指定类型,不指定长度
过程参数的三种模式:
IN 传入参数(默认)
OUT 传出参数 ,主要用于返回程序运行结果
IN OUT 传入传出参数
3.2.存储过程案例
添加业主信息
3.2.1.创建不带传出参数的存储过程
--增加业主信息序列 create sequence seq_owners start with 11; --增加业主信息存储过程 create or replace procedure pro_owners_add ( v_name varchar2, v_addressid number, v_housenumber varchar2, v_watermeter varchar2, v_type number ) is
begin insert into T_OWNERS values(seq_owners.nextval,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_type ); commit; end; |
PL/SQL中调用存储过程
call pro_owners_add('赵伟',1,'999-3','132-7',1); |
3.2.2.JDBC调用不带传出参数的存储过程
Junit测试
@Test public void andOwnerWithProc() throws Exception { Connection con=getCon(); String sql="{call PRO_OWNERS_ADD(?,?,?,?,?)}"; CallableStatement cst=con.prepareCall(sql); //设置输入参数 cst.setString(1, "佐助"); cst.setInt(2, 5); cst.setString(3, "35-902"); cst.setString(4, "30417"); cst.setInt(5, 1); //执行存储过程 cst.execute(); cst.close();
} |
删除业主信息存储过程
-- 删除业主的存储过程 -- create or replace procedure deleteOwner(oid number) is begin delete from t_owners where id = oid; end; |
修改业主信息的存储过程
注意:利用chr(39)转义单引号
-- 修改业主信息 -- create or replace procedure updateOwner ( v_id number, v_name varchar2, v_addressid number, v_housenumber varchar2, v_watermeter varchar2, v_ownertypeid number ) is sqlStr varchar2(200 char); -- 要执行的sql v_strLen number;-- 存储要执行的slq字符串的长度 begin sqlStr := 'update t_owners set '; dbms_output.put_line(v_name); if v_name is not null then sqlStr := sqlStr || ' name = "'||v_name||'",'; end if; if v_addressid <> 0 then sqlStr := sqlStr || ' addressId= '||v_addressid||','; end if; if v_housenumber is not null then sqlStr := sqlStr || ' housenumber= "'||v_housenumber||'",'; end if; if v_watermeter is not null then sqlStr := sqlStr || ' watermetere='||chr(39)||v_watermeter||chr(39)||','; end if; if v_ownertypeid <> 0 then sqlStr := sqlStr || ' ownertypeid= '||v_ownertypeid||','; end if; -- 删除最后一个"," -- -- 找出字符串的长度 -- select length(sqlStr) into v_strLen from dual; -- 通过subStr截取子串,去掉最后一个"," -- select substr(sqlStr,0,v_strLen-1) into sqlStr from dual; sqlStr := sqlStr || ' where id='||v_id; -- 将其中的双引号替换成单引号-- select replace(sqlStr,'"',chr(39)) into sqlStr from dual; -- 输出sql -- dbms_output.put_line(sqlStr); -- 执行sql语句 -- EXECUTE IMMEDIATE sqlStr; end;
call updateOwner(12,'佐助',5,'35-902','',0) |
3.2.3.创建带传出参数的存储过程
需求:添加业主信息,传出参数为新增业主的ID
--增加业主信息存储过程 create or replace procedure pro_owners_add2 ( v_name varchar2, v_addressid number, v_housenumber varchar2, v_watermeter varchar2, v_type number, v_id out number ) is begin select seq_owners.nextval into v_id from dual; insert into T_OWNERS values( v_id,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_type ); commit; end; |
PL/SQL调用该存储过程
declare v_id number;--定义传出参数的变量 begin pro_owners_add2('王旺旺',1,'922-3','133-7',1,v_id); DBMS_OUTPUT.put_line('增加成功,ID:'||v_id); end; |
执行成功后输出结果:
Junit 测试
@Test public void andOwnerWithProc1() throws Exception { Connection con=getCon(); String sql="{call pro_owners_add2(?,?,?,?,?,?)}"; CallableStatement cst=con.prepareCall(sql); //设置输入参数 cst.setString(1, "卡卡西"); cst.setInt(2, 5); cst.setString(3, "35-945"); cst.setString(4, "304444"); cst.setInt(5, 1); //输出参数要注册 cst.registerOutParameter(6, OracleTypes.NUMBER); //执行存储过程 cst.execute(); //取出输出参数的值 int id = cst.getInt(6); System.out.println("新添加的用户的id:"+id); cst.close();
} |