存储过程procedure+触发器triggger+游标cursor
来源:互联网 发布:vb简单小游戏代码 编辑:程序博客网 时间:2024/06/07 02:43
一,创建 t_procedure 表 存储过程要用到的表
create table t_procedure(
tid number not null ,
tname varchar2(10) ,
constraint yy primary key(tid)
);
二,创建存储过程
create or replace procedure save_pro
(
userid t_procedure.tid%type,
username t_procedure.tname%type
) //定义了存储函数 的变量,里面有两个变量 userid ,username ,也可以写死类型 像 userid in number
as
begin // 存储的逻辑体 ,从begin 开始
insert into t_procedure(tid,tname) values (userid,username); //把定义的变量插入表中
end save_pro;
三,在pl/sql 中执行procedure save_pro
call save_pro(10,'nb');,也可以用execute和exec。
四,在java 中运行
1,利用存储过程往Oracle里插入数值
第一步 在java project 里导入 Oracle 驱动 (文章后面有oracle5.jar 下载) build path -> add external
第二步 创建class ,在Oracle 里调用出save_pro,然后往存储函数里插入值
import java.sql.*;
import java.sql.ResultSet;
public class oracle_procedure {
public oracle_procedure() {
}
public static void main(String[] args ){
String driver = "oracle.jdbc.driver.OracleDriver"; //创建驱动
String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; //Oracle路径
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
CallableStatement cstmt = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, " odi_manager_test ", " odi_manager_test "); //路径,用户,密码
CallableStatement proc = null;
proc = conn.prepareCall("{ call savepro(?,?) }"); // 调用savepro 设定传2个参数
proc.setString(2, "马文涛"); //2是tname 字符串类型varchar
proc.setInt(1,10); //1是tid number
proc.execute(); //执行
}
catch (SQLException ex2) {
ex2.printStackTrace();
}
catch (Exception ex2) {
ex2.printStackTrace();
}
finally{
try {
if(rs != null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch (SQLException ex1) {
}
}
}
}
2,利用存储过程,在java里显示出Oracle数据
(1)1, 建一个程序包。如下: //游标,函数必须封装在包里
create or replace package userpackage as
type usercursor is ref cursor; //usercursor 是 游标类型
end userpackage;
(2)建立存储过程,存储过程为:
create or replace procedure pro_getalluser
(
pro_cursor out userpackage.usercursor //out 类型是Oracle往java输出,in类型是java往Oracle输入
)is //pro_cursor 定义为同包里的游标的类型一样
begin
open pro_cursor for select * from t_procedure; //打开游标,执行select
end pro_getalluser;
可以看到,它是把游标(可以理解为一个指针),作为一个out 参数来返回值的。
(3)java程序:
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import oracle.jdbc.OracleTypes;
public class TestProcedure {
public static void main(String[]args){
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; //根据实际情况
String user = "odi_manager_test"; //根据实际情况
String password = "odi_manager_test"; //根据实际情况
Connection con = DriverManager.getConnection(url, user, password);
String sql = "{call pro_getalluser(?)}";
CallableStatement cs = con.prepareCall(sql);
cs.registerOutParameter(1, OracleTypes.CURSOR); //注册out,(1位置,传对象类型)
cs.execute(); //执行
ResultSet rs = (ResultSet)cs.getObject(1); //返回结果集
while(rs.next()){
System.out.println(rs.getInt(1)+"----"+rs.getString(2)+"----");
}
rs.close();
cs.close();
con.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
触发器
after update on table_2 for each row //在update table_2 后触发
when ( NEW.departid>1) //判断条件
DECLARE //声明变量
v NUMBER;
begin update table_1 u set u.departid=:new.departid //别忘了分号
where u.departid=:old.departid;
dbms_output.put_line('x'); //oracle 输出
end t_table1;
CREATE OR REPLACE TRIGGER salary_raiu
AFTER INSERT OR UPDATE OF amount ON salary //插入或更新salary里的amount才会触发
FOR EACH ROW
when ( NEW.amount >= 1000 AND (old.amount IS NULL OR OLD.amount <= 500))
DECLARE
v_maxsalary NUMBER;
BEGIN
SELECT maxsalary
INTO v_maxsalary //变量赋值
FROM employment
WHERE employee_id = :NEW.employee_id;
IF :NEW.amount > v_maxsalary THEN //使用new 一定要在前面加 【:】
dbms_output.put_line('超工资');
END IF;
END;
二,instead of触发器,该触发器主要使用在对视图的更新上,
以下是instead of触发器的语法:
CREATE OR REPLACE TRIGGER trigger_name
INSTEAD OF <insert | update | delete> ON view_name
[FOR EACH ROW]
WHEN (condition)
DECLARE
BEGIN
END;
直接往视图里是插入不了数据的,要用触发器,往视图里插数据,然后再调用存储过程插入数据
代码如下:
新建员工表employment
CREATE TABLE EMPLOYMENT
(
)
CREATE TABLE SALARY
(
AMOUNT NUMBER --量
)
创建视图:
CREATE OR REPLACE VIEW EMPLOYEE_SALARY AS
SELECT a.employee_id, a.maxsalary, b.MONTH, b.amount
FROM employment a, salary b
WHERE a.employee_id = b.employee_id;
创建触发器
create or replace trigger employee_salary_rii
DECLARE //定义变量
BEGIN
--检查是否存在该员工信息
END employee_salary_rii;
语句级触发器的语法:
CREATE OR REPLACE TRIGGER trigger_name
<before | after | instead of ><insert | update | delete > ON table_name
DECLARE
BEGIN
--触发器主体
END;
创建触发器
CREATE OR REPLACE TRIGGER salary_saiu
AFTER INSERT OR UPDATE OF amount ON salary
DECLARE
v_sumsalary NUMBER;
BEGIN
END;
创建临时表
create global temporary table SALARY_TMP
(
)
为了把操作记录插入到临时表中,创建行级触发器:
CREATE OR REPLACE TRIGGER salary_raiu
AFTER INSERT OR UPDATE OF amount ON salary
FOR EACH ROW
BEGIN
END;
该触发器的作用是把更新后的记录信息插入到临时表中,如果更新了多条记录,则每条记录都会保存在临时表中。
创建语句级触发器:
CREATE OR REPLACE TRIGGER salary_sai
AFTER INSERT OR UPDATE OF amount ON salary
DECLARE
BEGIN
END;
该触发器首先用游标从salary_tmp临时表中逐条读取更新或插入的记录,取employee_id,在关联表salary中查找所有相同员工的 工资记录,并求和。若某员工工资总和超过50000,则抛出异常。如果检查通过,则清空临时表,避免下次检查相同的记录。
游标例子
declare
cursor cursor_user
is
select username,age
from t_user;
a t_user.username%type; //定义变量
b t_user.age%type; //定义变量
begin
open cursor_user;
loop
fetch cursor_user into a,b;
if a='宝宝'and b=43 then
dbms_output.put_line(a || ' ' || b);
end if;
exit when cursor_user%notfound;
end loop;
close cursor_user;
end;
用包封装触发器代码
目的:改写例五,封装触发器主体代码
创建代码包:
CREATE OR REPLACE PACKAGE BODY salary_trigger_pck IS
i_employee_id IN NUMBER,
END load_salary_tmp;
END salary_trigger_pck;
包salary_trigger_pck中有两个存储过程,load_salary_tmp用于在行级触发器中调用,往 salary_tmp临时表中装载更新或插入记录。而check_salary用于在语句级触发器中检查员工累计工资 是否超限。
修改行级触发器和语句级触发器:
CREATE OR REPLACE TRIGGER salary_raiu
BEGIN
END;
CREATE OR REPLACE TRIGGER salary_sai
AFTER INSERT OR UPDATE OF amount ON salary
BEGIN
END;
这样主要代码就集中到了salary_trigger_pck中,触发器主体中只实现了一个调用功能。
10,触发器命名规范
为了方便对触发器命名和根据触发器名称了解触发器含义,需要定义触发器的命名规范:
Trigger_name = table_name_trg_<R|S><A|B|I><I|U|D>
触发器名限于30个字符。必须缩写表名,以便附加触发器属性信息。
<R|S>基于行级(row)还是语句级(statement)的触发器
<A|B|I>after, before或者是instead of触发器
<I|U|D>触发事件是insert,update还是delete。如果有多个触发事件则连着写
例如:
Salary_rai
Employee_sbiud
- 存储过程procedure+触发器triggger+游标cursor
- 笔记081121 游标(cursor)和存储过程(procedure)
- 游标(cursor)、函数(function)、存储过程(procedure)
- oracle 游标,函数 function , 存储过程 PROCEDURE , 触发器 Trigger
- 游标,存储过程,触发器
- Mybatis 调用多游标参数存储过程 Mybatis Oracle Procedure multi cursor
- MySql存储过程 游标(Cursor)
- 5.存储过程 游标 触发器
- 游标、触发器、存储过程实例
- 包 存储过程 触发器 游标
- 游标,存储过程,触发器,事务
- Mysql -- 存储过程/触发器/游标
- 【MySQL】存储过程 游标 触发器
- MySQL存储过程+游标+触发器
- MySQL 触发器、存储过程、游标
- ORACLE语法-包(package)、存储过程(procedure)、游标(cursor)以及java对Result结果集的处理
- mysql 存储过程游标(Cursor)实例
- MySql存储过程—7、游标(Cursor)
- linux(readhat) yum源安装
- 面试题 求二叉树的深度
- awk中printf的使用说明
- HDU3652 B-number
- Java dom4j解析RESTFull风格发布的WebService的xml文件
- 存储过程procedure+触发器triggger+游标cursor
- 建立两数据库之间的连接,跨数据库访问数据
- PHP与API开发的人
- CSUOJ 1102 多色块拼图(进制转换,脑洞略大)
- Android组件:Fragment切换后保存状态
- 产品粘性的用户自我感知
- 东莞南城东城最好的400电话办理公司选心网科技
- CSS 发明者 Håkon Wium Lie 访谈(三)
- spring 容器初始化 bean 和销毁前所做的操作