Oracle备忘录(十二)--存储过程,数据字典,触发器,jdbc调用存储过程
2014-07-19 01:39
555 查看
------***********----数据字典----********------------- --表分两种: --用户表:包含商业数据,用户自己维护 --数据字典:管理员维护(用户只能查,不能改) --数据字典命名规则: --USER 用户自己的 --ALL 用户可以访问到的 --DBA 管理员视图(管理员用户才能看到) --V$ 性能相关的设置(数据) select * from dictionary; --创建一个注释: comment on table emp is '这是员工信息表'; --查看注释 select *from user_tab_comments where table_name='emp'; select * from session_privs; --查看用户有的权限 -------**********-----触发器-----***********--------- /* 成功插入员工后,自动输出“成功插入一个新员工” CREATE [or REPLACE] TRIGGER 触发器名 {BEFORE | AFTER} {DELETE | INSERT | UPDATE [OF 列名]} ON 表名 PLSQL 块 */ create or replace trigger sayNewEmp after insert on emp begin dbms_output.put_line('成功插入一个新员工'); end; / /* --实施复杂的安全性检查 --禁止在非工作时间 往emp表中插入数据 -- CREATE [or REPLACE] TRIGGER 触发器名 -- {BEFORE | AFTER} -- {DELETE | INSERT | UPDATE [OF 列名]} -- ON 表名 -- PLSQL 块 --周末:to_char(sysdate,'day') in ('星期六','星期日') --上班前 下班后: to_number(to_char(sysdate,'hh24')) not between 9 and 18 */ create or replace trigger securityEmp before insert on emp begin if to_char(sysdate,'day') in ('星期六','星期日') or to_number(to_char(sysdate,'hh24')) not between 9 and 18 then raise_application_error(-20001,'不能在非工作时间插入数据'); end if; end; / /* --数据确认 --涨后的薪水不能少于涨前的薪水 -- CREATE [or REPLACE] TRIGGER 触发器名 -- {BEFORE | AFTER} -- {DELETE | INSERT | UPDATE [OF 列名]} -- ON 表名 -- [FOR EACH ROW [WHEN(条件) ] ] -- PLSQL 块(begin ... end; ) */ create or replace trigger checksal before update on emp --在一次操作表的语句中,每操作成功一行就会触发一次; --不写的话,表示是表级触发器,则无论操作多少行,都只触发一次 for each row begin --if 涨后的薪水< 涨前的薪水 then if :new.sal < :old.sal then raise_application_error(-20002,'涨后的薪水不能少于涨前的薪水.涨前:'||:old.sal||' 涨后:'||:new.sal); end if; end; / --:NEW 和:OLD使用方法和意义: --new 只出现在insert和update时, --old只出现在update和delete时。 --在insert时new表示新插入的行数据,update时new表示要替换的新数据。 --old表示要被更改的原来的数据行,delete时old表示要被删除的数据。 ------**********-------存储过程---------************------ --1.存储过程可以使得程序执行效率更高、安全性更好, -- 因为过程建立之后 已经编译并且储存到数据库, -- 直接写sql就需要先分析再执行因此过程效率更高, -- 直接写sql语句会带来安全性问题,如:sql注入 --2.建立过程不会很耗系统资源,因为过程只是在调用才执行。 --3.存储过程可以用于降低网络流量,存储过程代码直接存储于数据库中, -- 所以不会产生大量T-sql语句的代码流量。 --4.使用存储过程使您能够增强对执行计划的重复使用 /* create [or replace] PROCEDURE 过程名(参数列表) AS PLSQL子程序体; 打印Hello World 调用存储过程 1. exec sayHelloWorld(); 2. begin sayHelloWorld(); sayHelloWorld(); end; / */ create or replace procedure sayHelloWorld as --说明部分 begin dbms_output.put_line('Hello World'); end; / /* create [or replace] PROCEDURE 过程名(参数列表) AS PLSQL子程序体; --为指定的员工涨100块钱 并打印涨前和涨后的薪水 */ create or replace procedure raiseSalary(eno in number) as psal emp.sal%type; begin --涨前薪水 select sal into psal from emp where empno=eno; --涨100 update emp set sal=sal+100 where empno=eno; --要不要commit??? dbms_output.put_line('涨前:'||psal||' 涨后:'||(psal+100)); end; / -----------------带out参数的调用------------------- create or replace procedure p1(pno in number,pname out varchar2) as begin select ename into pname from emp where empno=pno; dbms_output.put_line(pname||' '||pno); end; / 方法一: set serveroutput on var a varchar2(20); exec P1(7566,:a); 方法二: set serveroutput on declare pname varchar2(20); begin p1(&pno,pname); end; / ------------------------ /* --用java程序调用 create [or replace] PROCEDURE 过程名(参数列表) AS PLSQL子程序体; --查询并返回某个员工的姓名 月薪和职位 */ create or replace procedure queryEmpInfo(eno in number, pename out varchar2, psal out number, pjob out varchar2) as begin select ename,sal,empjob into pename,psal,pjob from emp where empno=eno; end; / ------************存储函数-------------**********--- --oracle中的Function有两种: --一种是系统内置的函数(直接拿来用就行)。 --一种是自定义的(自己写的完成特定功能的)。 --function可以在DML语句中执行。 --如select upper('AaBbCcDd') '大写' from dual --其中upper就是系统自带的函数,是把参数中的字符串变成大写字符。 /** CREATE [OR REPLACE] FUNCTION 函数名(参数列表) RETURN 函数值类型 AS PLSQL子程序体; --查询某个员工的年收入 */ create or replace function queryEmpIncome(eno in number) return number as psal emp.sal%type; pcomm emp.comm%type; begin select sal,comm into psal,pcomm from emp where empno=eno; return psal*12+nvl(pcomm,0); end; / 调用一:select 函数名 from dual; ------------******package*****-------------- 解决的问题:返回值是一个集合 查询某个部门中 所有员工的所有信息 包头 CREATE OR REPLACE PACKAGE MYPACKAGE AS type empcursor is ref cursor; procedure queryEmpList(dno in number,empList out empcursor); END MYPACKAGE; 包体 CREATE OR REPLACE PACKAGE BODY MYPACKAGE AS procedure queryEmpList(dno in number,empList out empcursor) AS BEGIN open empList for select * from emp where deptno=dno; END queryEmpList; END MYPACKAGE;
package demo.test;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;
import org.junit.Test;
import demo.utils.JDBCUtils;
public class TestOracle {
/*
* create or replace procedure queryEmpInfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
*/
@Test
public void testProcedure(){
//{call <procedure-name>[(<arg1>,<arg2>, ...)]}
String sql = "{call queryEmpInfo(?,?,?,?)}";
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);
System.out.println(sal);
System.out.println(job);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);
}
}
/*
* create or replace function queryEmpIncome(eno in number)
return number
*/
@Test
public void testFunction(){
// {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
String sql = "{?=call queryEmpIncome(?)}";
Connection conn = null;
CallableStatement call = null;
try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql);
//对于out参数,申明
call.registerOutParameter(1, OracleTypes.NUMBER);
//对于in参数,赋值
call.setInt(2, 7839);
//执行
call.execute();
//取出结果
double income = call.getDouble(1);
System.out.println(income);
}catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);
}
}
@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+"的薪水是"+sal);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, rs);
}
}
}
相关文章推荐
- DB2数据库、触发器、存储过程、JAVA数据库链接(JDBC)、调用层接口(CLI)
- jdbc调用存储过程-oracle版 返回游标
- Oracle 存储过程,Hibernate 调用存储过程,JDBC调用存储过程,Oracle 动态SQL
- 触发器调用存储过程处理脏数据
- Oracle基本操作十二:存储过程及定时调用存储过程
- jdbc调用oracle procedure传递/返回批量数据
- oracle创建定时job,job调用存储过程,批量查询,批量修改,自定义数据类型,
- 游标、例外、存储过程、存储函数、java调用存储过程、触发器(Oracle之二)
- Oracle中通过:触发器,存储过程,Function调用实现解析Clob字段类型中存储的xml字符串
- 触发器,存储过程,oracle调用java方法
- hibernate里使用jdbc方式调用oracle带游标返回参数的简单分页存储过程
- jdbc 连接oracle调用表数据
- jdbc调用存储过程-oracle版 返回游标
- java 调用Oracle 存储过程 Jdbc/Hibernate
- Oracle 触发器调用存储过程
- 创建oracle的存储过程,以及通过JDBC调用该存储过程
- DB2数据库、触发器、存储过程、JAVA数据库链接(JDBC)、调用层接口(CLI)
- 深入了解Oracle数据字典升级脚本catupgrd.sql调用过程
- j2ee规范-jdbc-存储过程调用(oracle为例)
- 游标、例外、存储过程、存储函数、java调用存储过程、触发器(Oracle之二)