oracle取字段后四码,Oracle学习笔记四

一、PL/SQL编程

游标(光标Cursor)

为什么使用游标

319fb27b9f866826dce551e9198ef0ff.png

在写java程序中有集合的概念,那么在pl/sq中也会用到多条记录,这时候我们就要用到游标,游标可以存储查询返回的多条数据。

语法:

CURSOR 游标名 [(参数名数据类型,参数名数据类型…,] IS SELECT语句;

例如:

cursor c1 is select ename from emp;

游标的使用步骤:

打开游标: open c1;(打开游标执行查询)

取一行游标的值: fetch c1 into job:(取一行到变量中)

关闭游标: close c1;(关闭游标释放资源)

游标的结束方式: exit when c1%notfound

注意:上面的pjob必须与emp表中的job列类型一致

定义:

pjob emp. empjob%type;

范例1:使用游标方式输出emp表中的员工编号和姓名

declare

cursor pc is

select * fromemp;

pemp emp%rowtype;begin

openpc;

loopfetchpcintopemp;exit when pc%notfound;

dbms_output.put_line(pemp.empno II’ ‘II pemp.ename);endloop;closepc;end;

范例2:写一段PL/SQL程序,为部门号为10的员工涨工资

declare

cursor pc(dno myemp.deptno% type) is

select empno from myemp where deptno =dno;

pno myemp.empno%type;begin

open pc(20);

loopfetchpcintopnoexit when pc%notfound;update myemp t set t.sal = t.sal + 1000 where t.empno =pno;endloop;close pc;

●例外

异常是程序设计语言提供的一种功能,用来增强程序的健壮性和容错性。

系统定义异常

no_data_found(没有找到数据)

too_many_rows( (select.into语句匹配多个行)

zero_ divide(被零除)

value_error(算术或转换错误)

timeout_on_resource(在等待资源时发生超时)

范例1:写出被0除的异常的psq程序

declarepnumnumber

beginpnum:=1/0;

exceptionwhen zero_divide thendbms_ output.put_line('被0除');when value_error thendbms_ output.put_line('数值转换错误');when others thendbms_ output.put_line('其他错误');end:

用户也可以自定义异常,在声明中来定义异常

DECLAREMy_jobchar(10);

v_sal emp.sal%type;

No_data exception;cursor cl is select distinct job from emp order by job;

如果遇到异常我们要抛出 raise no_data;

范例2:查询部门编号是50的员工

declareno_emp_found exception;cursor pemp is

select t.ename from emp t where t.deptno = 50;

pename emp.ename%type;begin

openpemp;fetchpempintopename;if pemp%notfound thenraise no_emp_found;end if;closepemp;

exceptionwhen no_emp_found thendbms_output.put_line(’没有找到员工');

when others then

dbms_output.put_line(’其他错误’);

end:

二、存储过程

存储过程( Stored procedure)是在大型数据库系统中,一组为了完成特定功能的SQL句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程

创建存储过程语法:

create [or replace] PROCEDURE过程名 [(参数名in/out数据类型])AS

beginPLSQL子程序体;End:

或者

create [or replace] PROCEDURE过程名 [(参数名in/out数据类型)]

is

beginPLSQL子程序体

End过程名;

范例1:给指定的员工涨100工资,并打印出涨前和涨后的工资

分析:我们需要使用带有参数的存储过程

create or replace procedure addSall(eno in number) ispemp myempo%rowtypebegin

select * into pemp from myemp where empno =eno;update myemp set sal = sal + 100 where empno =eno;

dbms_ output.put_line('涨工资前’||pemp.sal||'涨工资后’||(pemp.sa1+100));end addSall;

调用:

begin

--Call the procedure

addSall(eno=> 7902);commit;end:

三、存储函数

create or replace function函数名 (Name in type, Name out type,…) return数据类型 is结果变量 数据类型begin

return(结果变量);end[函数名];

存储过程和存储函数的区别:

一般来讲,过程和函数的区别在于函数可以有一个返回值,而过程没有返回值;

但过程和函数都可以通过out指定一个或多个输出参数。我们可以利用out参数,在过程和函数中实现返回多个值。

范例:使用存储函数来查询指定员工的年薪

create or replace function empincome(eno in emp.empno%type)return number ispsal emp.sal%type;

pcomm emp.comm%type;begin

select t.sal into psal from emp t where t.empno =eno;return psal * 12 + nvl(pcomm, 0);end;

使用存储过程来替换上面的例子

create or replace procedure empincomep(eno in emp. empno%type,

income outnumber) ispsal emp.sal%type;

pcomm emp.comm%type;begin

select t.sal, t.comm into psal, pcomm from emp t where t.empno =eno;

income := psal*12 + nvl(pcomm,0);end empincomep;

调用:

declareincomenumber;beginempincomep(7369,income);

dbms_output.put_line(income);end:

四、触发器

数据库触发器是一个与表相关联的、存储的PL/SQL程序。每当一个特定的数据操作语句( insert, update, delete)在指定的表上发出时, Oracle自动地执行触发器中定义的语句序列。

4.1触发器的作用

1.数据确认

示例:员工涨后的工资不能少于涨前的工资

2.实施复杂的安全性检查

示例:禁止在非工作时间插入新员工

3.做审计,跟踪表上所做的数据操作等

4.数据的备份和同步

4.2 触发器的类型

√语句级触发器

在指定的操作语句操作之前或之后执行一次,不管这条语句影响了多少行。

√行级触发器( FOR EACH ROW)

触发语句作用的每一条记录都被触发。在行级触发器中使用old和new伪记录变量,识别值的状态

CREATE[or REPLACE]TRIGGER触发器名

{BEFORE I AFTER}

{DELETE| NSERT| UPDATE [OF列名]}

ON表名[FOR EACH ROW [WHEN条件)]]declare......

PLSQL块end 触发器名

范例:插入员工后打印一句话“一个新员工插入成功”

create or replace triggertestTrigger

afterinsert onpersondeclare

--local variables here

begindbms_output.put_line('一个员工被插入');end testTrigger;

范例:不能在休息时间插入员工

create or replace triggervalidInsertPerson

beforeinsert onpersondeclareweekendvarchar2(10)ibegin

select to_char (sysdate, 'day') into weekend fromdual;if weekend in(‘星期一’) thenraise_application_error(-20001,’不能在非法时间插入员工’);end if;end validInsertPerson:

当执行插入时会报错

202abec468d0d92931ba4eb59aa9caf9.png

在触发器中触发语句与伪记录变量的值

34149be5bedb8d0212864a6588ace69f.png

范例:判断员工涨工资之后的工资的值一定要大于涨工资之前的工资

create or replace triggeraddsal4p

beforeupdate of sal onmyempforeach rowbegin

if :old.sal >= :new.sal thenraise_application_error(-20002,'涨前的工资不能大于涨后的工’);

end if;

end;

调用

update myemp t set t.sal = t.sal - 1 ;

4.3 触发器的实际应用

需求:使用序列,触发器来模拟mysq中自增效果

4.3.1 创建序列

1、建立表

create table user(idnumber(6) not null,

namevarchar2(30) not null primary key)

2 建立序列SEQUENCE

create sequence user_seq:

4.3.2 创建自增的触发器

分析:创建一个基于该表的before insert触发器,在触发器中使用刚建的SEQUENCE

create or replace triggeruser_trigger

beforeinsert on user

foreach rowbegin

select user_seq.nextval into :new. id fromsys.dual;end;

4.3.3 测试效果

insert into user(name) values( ‘Kevin1’);

commit;insert into user(name) values( ‘Kevin2’);

commit;

五、Java程序调用存储过程

5.1 Java连接Oracle的jar包

在Java项目中导入连接Oracle数据库所需要的jar包。

5.2 数据库连接字符串

String driver = "Oracle.jdbc.OracleDriver";

String url= "jdbc:oracle:thin:@10.131.68.66:1521:orcl ";

String username= "scott";

String password= "admin";

测试代码:

3b6006a86fdbf9482ad2ea5047d96ba9.png

5.3 实现过程的调用

5.3.1 过程定义

2ab5eca2ef21346328340ddb4a97f8c3.png

5.3.2 过程调用

d8d9048d68154c14dc8c1fea13c83077.png

5.4 游标引用的Java测试

5.4.1 定义游标,并返回引用型游标

ce3e8d6675daa5a1869f2bbfa5f87063.png

5.4.2 Java代码调用游标类型的out参数

c0d6de6375619f7597be0a70eef5b9eb.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值