Oracle學習總結5-存儲過程,存儲函數,觸發器
阿新 • • 發佈:2017-06-12
app 存儲過程 stat stack ber varchar2 pin rec style
二.存儲過程與存儲函數:procedure
1.hello world
create or replace procedure hello_world is begin dbms_output.put_line(‘hello world‘); end hello_world;
2. --給指定員工漲100工資,並打印漲前漲後的薪水(存儲過程)
create or replace procedure raiseSalary(eno in number) is psal emp.sal%type; begin select sal into psal fromemp where empno=eno; update emp set sal=sal+100 where empno=eno; dbms_output.put_line(‘漲前:‘||psal||‘漲後:‘||(psal+100)); end raiseSalary;
3. --查詢某個員工的年收入(存儲函數)
create or replace function queryEmpIncome(eno in number) return number is income number; begin select sal*12+nvl(comm,0) intoincome from emp where empno=eno; return income; end queryEmpIncome;
4. --查詢某個員工的姓名薪水和職位
create or replace procedure queryEmpInformation(eno in number,pename out varchar2,psal out number,pjob out varchar2) is begin select ename,sal,job into pename,psal,pjob from emp where empno=eno; end queryEmpInformation;
5. --查詢某個員工的年收入的java調用(存儲函數調用)
//存儲函數調用 @Test public void testFunction(){ String sql = "{?=call queryEmpIncome(?)}"; Connection conn = null; CallableStatement call = null; try { conn=JDBCUtils.getConnection(); call=conn.prepareCall(sql); //返回值聲明 call.registerOutParameter(1, OracleTypes.NUMBER); //對於in參數,賦值 call.setInt(2,7839); //執行 call.execute(); //輸出 double income=call.getDouble(1); System.out.println(income); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JDBCUtils.release(conn, call, null); } }
6. --查詢某個員工的姓名薪水和職位的java調用(存儲過程調用)
@Test public void testProcedure(){ String sql = "{call queryEmpInformation(?,?,?,?)}"; Connection conn = null; CallableStatement call = null; try { conn=JDBCUtils.getConnection(); call=conn.prepareCall(sql); //對於in參數,賦值 call.setInt(1,7839); //對於out參數,申明 call.registerOutParameter(2, OracleTypes.VARCHAR); call.registerOutParameter(3, OracleTypes.NUMBER); call.registerOutParameter(4, OracleTypes.VARCHAR); //執行 call.execute(); //輸出 String name=call.getString(2); double sal=call.getDouble(3); String job=call.getString(4); System.out.println(name+"---"+sal+"---"+job); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JDBCUtils.release(conn, call, null); } }
7.返回多列-使用光標實現。Plsql中建立包和體的結構。然後再由java中的resultset接收
Plsql中:
包:
create or replace package mypackage is type empcursor is ref cursor; procedure queryEmpList(dno in number,empList out empcursor); end mypackage;
體:
create or replace package body mypackage is procedure queryEmpList(dno in number,empList out empcursor) as begin open empList for select * from emp where deptno=dno; end; end mypackage;
java調用:
//存儲函數調用,返回光標類型的 @Test public void testCursor(){ String sql = "{call mypackage.QUERYEMPLIST(?,?)}"; Connection conn = null; CallableStatement call = null; ResultSet rs = null; try { conn = JDBCUtils.getConnection(); call = conn.prepareCall(sql); //對於in參數,賦值 call.setInt(1,20); //對於out參數,申明 call.registerOutParameter(2, OracleTypes.CURSOR); //執行 call.execute(); //取出結果 rs = ((OracleCallableStatement)call).getCursor(2); while(rs.next()){ //取出一個員工 String name = rs.getString("ename"); double sal = rs.getDouble("sal"); System.out.println(name+"\t"+sal); } } catch (Exception e) { e.printStackTrace(); }finally{ JDBCUtils.release(conn, call, rs); } }
三.觸發器(trigger)
1. 插入員工時候觸發
create or replace trigger firsttrigger after insert on emp declare begin dbms_output.put_line(‘成功插入新員工‘); end firsttrigger;
2. --不允許在非工作時間插入數據
create or replace trigger securityemp before insert on emp declare begin if to_char(sysdate,‘day‘) in (‘星期六‘,‘星期日‘) or to_number(to_char(sysdate,‘hh24‘)) not between 9 and 17 then raise_application_error(-20001,‘禁止在非工作時間插入新員工‘); end if; end securityemp;
3. --不允許降薪
create or replace trigger checksalary before update on emp for each row declare begin if :new.sal<:old.sal then raise_application_error(-20002,‘漲後的薪水不能少於漲前的薪水。漲前:‘||:old.sal||‘ 漲後:‘||:new.sal); end if; end checksalary;
Oracle學習總結5-存儲過程,存儲函數,觸發器