1:存储过程 就是一个PL/SQL块的名称。经过这个名称来调用过程。sql
存储过程,保存在服务器上,之后经过名称来调用,而后由服务来执行的代码块。 1:不接收参数的过程 (略) Create or replace procedure p1 As Age int; Begin …. End;服务器
2:接收参数的存过程函数
参数的声明: p2(参数名称 [输入in或是输出out类型默认是输入的参数] 参数类型 , 。。。。)oop
--开发一个过程,接收name,age两个参数,保存到数据表中去 create or replace procedure p2(nm in varchar,ag in int) as begin insert into person values(sys_guid(),nm,ag); end;fetch
3:返回参数的值
--开发一个过程,接收name,age两个参数,保存到数据表中去 - 只要out类型的,则pid在传递时,必须是一个变量 create or replace procedure p2(nm in varchar,ag in int,pid out varchar) as begin select sys_guid() into pid from dual;--给返回类型的值赋值 insert into person values(pid,nm,ag); end;ui
--调用这个过程,保存数据 --在另外一个pl/块中来调用 declare vpid varchar(32); begin p2('李四',99,vpid); dbms_output.put_line('新的id是'||vpid); end;指针
select * from person;开发
能够省去一些参数,声明参数为 输入+输出类型的:it
--开发一个过程,接收name,age两个参数,保存到数据表中去 - 只要out类型的,则pid在传递时,必须是一个变量 create or replace procedure p2(nm in out varchar,ag in int,cnt out int) as vpid varchar(32); begin select sys_guid() into vpid from dual; insert into person values(vpid,nm,ag); nm:=vpid; select count(1) into cnt from person; end;io
--调用这个过程,保存数据 --在另外一个pl/块中来调用 declare vpid varchar(32):='赵七'; vcnt int; begin p2(vpid,99,vcnt); dbms_output.put_line('新的id是'||vpid||' 记录的数量是:'||vcnt); end;
select * from person;
参数的顺序:
=> 相似于 C++
2:存储函数 – 用户自定义的函数
函数与过程的区别: 函数必需要至少返回一个值。 1~N 过程能够返回0~N 函数能够用于查询或是赋值。 Selectd f1(..) from …; Nm:=f1(…); 而过程只能是调用。
实现+操做: create or replace function f1(a int,b int) return number as vsum int; begin vsum:=a+b; return vsum; end;
select f1(1,4) from dual;
select f1(age,100),name,age from person;
declare aa int; begin aa:=f1(4,55); dbms_output.put_line(aa); end;
3:触发器 trigger 函数,过程 – 都是让用户能够调用 的。
触发器- 保存在服务器上的一段pl/sql块 与 表相关。当达到某个条件时,由服务器来调用的代码块。
功能: 1:实现更加严格的约束 。 2:实现表之间数据的自动维护。
3.一、建立一个触发器的示例 当向person表中写入一行记录之后,就输出一个句,说 一行记录成功了。
3.二、分类 按影响的行数 表级触发器- 默认的。 与行数无关,只触发一次。 create or replace trigger t1 after delete on person declare begin dbms_output.put_line('数据已经删除了'); end;
行级触发器
在行级的触发器上,能够使用两个隐藏变量:
变量 insert Update Delete :NEW 可用 可用 不可用 :OLD 不能用 可用 可用
要求当修改记录时,检查,新修改的年龄是否大于当前的年龄:
分析:在 person表上添加 before update约束。
列级的的触发器 – 按是否指定列 – 列级的触发器只能用于update
指定只是修改age时才触发:
按是否有条件,能够分为条件触发器 当达到某个条件时,才会触发
3.3 使用原则
4:应用 限制一个表在上班时能够写入,下班之后,就不能再写入了: 8:00 ~ 17:00
表之间的自维护: 班级与学生的关系。
一个班有不少的学生。
create table cls( id varchar(32) primary key, name varchar(30), cnt int );
create table studs( id varchar(32) primary key, name varchar(30), clsid varchar(32) , constraint fk1 foreign key(clsid) references cls(id) );
create or replace trigger t2 after insert on studs FOR EACH ROW declare begin update cls set cnt=cnt+1 where id=:NEW.clsid; end;
insert into cls values('C001','一班',0);
insert into studs values('S002','Mary','C001');
select * from cls;
做业: 请实现学生删除时,修改学生班级维护。
5:游标 cursor(光标)
游标是指向记录集的一个指针。 一次,只能指向一行记录。
游标的分类: 1:隐式的游标 – 》Oracle在执行DML操做时使用的游标。 - 》 隐式的游标的名称叫:SQL 2:显式的游标 – 》 用户本身定义的游标。 1:静态游标。 2:动态游标。
游标属性: 变量 功能 SQL%rowCount 返回当前影响的行数。 SQL%notFound 没有指到记录的行上,即指到了行首或是行尾 SQL%isOpen 游标是打开的吗
对游标的操做: 显示游标的 定义游标 打开游标 遍历执行 关闭游标
1:查看隐式的游标 declare vrow int; begin update person set age=age+1; vrow:=SQL%rowCount; dbms_output.put_line('影响了几行呀'||vrow); if not SQL%isOpen then dbms_output.put_line('已经关了 '); end if; end;
2:自定义的游标 定义游标 打开游标 遍历执行 关闭游标
1:静态的游标
declare cursor cur is select id,name,age from person; --定义游标 vid varchar(30); vname varchar(30); vage int; begin --打开游标 open cur; --遍历游标 loop fetch cur into vid,vname,vage; --先作判断有数据 exit when cur%notFound; dbms_output.put_line(vid||','||vname||','||vage); end loop; --关闭游标 close cur; --用异常处理游标的必须关闭 exception when others then if cur%isOpen then close cur; end if; end;
select * from person;
静态游标的变体:参数游标 declare cursor cur(nm varchar)[] is select id,name,age from person where name like '%'||nm||'%[]'; --定义游标 vid varchar(30); vname varchar(30); vage int; begin --打开游标 open cur('a');[] --遍历游标 loop fetch cur into vid,vname,vage; --先作判断有数据 exit when cur%notFound; dbms_output.put_line(vid||','||vname||','||vage); end loop; --关闭游标 close cur; --用异常处理游标的必须关闭 exception when others then if cur%isOpen then close cur; end if; end;
declare cursor cur(nm varchar) is select id,name,age from person where name like '%'||nm||'%'; --定义游标 vperson person%rowType; begin --打开游标 open cur('%'); --遍历游标 loop fetch cur into vperson; --先作判断有数据 exit when cur%notFound; dbms_output.put_line(vperson.id||','||vperson.name||','||vperson.age); end loop; --关闭游标 close cur; --用异常处理游标的必须关闭 exception when others then if cur%isOpen then close cur; end if; end;
2:动态的游标 在定义时,不指定查询的语句,而是在打开游标时才指定执行哪个查询语句。
在定义时,先定义一个自定义的数据类型: declare --定义一个数据类型,这个类型是动态的游标类型,即定义一个类 type ref_cur is ref cursor; --再根据上面的类型,定义一个变量 cur ref_cur; vperson person%rowType; begin --打开游标 时指定SQL open cur for 'select * from person'; --遍历游标 loop fetch cur into vperson; --先作判断有数据 exit when cur%notFound; dbms_output.put_line(vperson.id||','||vperson.name||','||vperson.age); end loop; --关闭游标 close cur; --用异常处理游标的必须关闭 exception when others then if cur%isOpen then close cur; end if; end;
6:请开发一个PL/SQL块,删除某个用户的全部表 就遍历 user_tables表,查询这个用户的全部表,组成SQL语句(drop语句),执行 Drop就能够了。
declare cursor cur is select table_name from user_tables; cursor cur2 is select constraint_name,table_name from user_constraints where constraint_type='R'; tname varchar(30); cname varchar(30); vsql varchar(100); begin open cur2; loop fetch cur2 into cname,tname; exit when cur2%notfound; vsql:='alter table '||tname||' drop constraint '||cname; dbms_output.put_line(vsql); EXECUTE IMMEDIATE vsql; end loop; close cur2; open cur; loop fetch cur into tname; exit when cur%notfound; vsql:='drop table '||tname; dbms_output.put_line(vsql); --执行上面的vsql,将这个vsql语句让Oracle数据来执行 EXECUTE IMMEDIATE vsql; end loop; close cur; end;
select constraint_name,table_name from user_constraints where constraint_type='R';
请实现删除里面的全部 view,triiger,procedure
create or replace procedure p1 as cursor cur is select table_name from user_tables; cursor cur2 is select constraint_name,table_name from user_constraints where constraint_type='R'; tname varchar(30); cname varchar(30); vsql varchar(100); begin open cur2; loop fetch cur2 into cname,tname; exit when cur2%notfound; vsql:='alter table '||tname||' drop constraint '||cname; dbms_output.put_line(vsql); EXECUTE IMMEDIATE vsql; end loop; close cur2; open cur; loop fetch cur into tname; exit when cur%notfound; vsql:='drop table '||tname; dbms_output.put_line(vsql); --执行上面的vsql,将这个vsql语句让Oracle数据来执行 EXECUTE IMMEDIATE vsql; end loop; close cur; end;
exec p1;
7:表空间 查看表空间及对应的文件:
查询某个用户保存数据用的是哪个表空间:
建立一个新的表空间
建立一个新的用户,这个用户使用qlc作为表空间
alter TABLESPACE qlu add datafile 'C:\qlu3.dbf' size 128K AUTOEXTEND off;