PLSQL语言(二)

24 比普通员工最高薪水还要高的经理人

select ename from emp where empno in
(select distinct mgr from emp where mgr is not null)
and sal >
(
select max(sal) from emp where empno not in
(select distinct mgr from empwhere mgr is not null)
)

/

求部门经理人中平均薪水最低的部门名称


求薪水最高的前5名员工

select ename ,sal from (
select ename,sal from emp order by sal desc)
where rownum <=5


求薪水最高的第6到第10名员工(重点掌握)

select ename,sal from (
select rownum r,ename,sal from
(
select ename,sal from emp order by sal desc
))
where r >5 and r <= 10

1-- backup scott
exp

2-- create user
create user jetwu identified by jetwu default tablespace users quota 10M on users
grant create session--登录权限, create table, create view to jetwu

3-- import the data
imp


--备份一张表
create table emp2 as select * from emp;

insert into dept2 select * from dept;

rownum
--取15条记录中后5条记录值
select ename from (select rownum r, ename from emp) where r > 10;

--取薪水最高的5个人
select ename, sal from
(select ename,sal from emp order by sal desc) where rownum <=5;

--取薪水最高的6到10
select ename, sal from
(
select ename, sal, rownum r from
(
select ename, sal from emp order by sal desc
)
)
where r >=6 and r <=10;


3张表S,C,SC
S(SNO,SNAME)
C(CNO,CNAME,CTEACHER)
SC(SNO,CNO,SCGRADE)
1.找出没选过黎明老师的所有学生姓名
2.列出2门以上(含2门)不及格学生姓名及平均成绩
3.即学过1号课又学过2号课所有学生的姓名
1.select ename from s join sc on(s.sno=sc.sno) join c on(c.cno = sc.cno) where c.cteacher <> '黎明';
2.select s.sname sc.avg(scgrade) from s s,sc sc where s.sno = sc.sno and
sc.scgrade < 60 group by sc.sno having count(*) >=2

3.
select sname from s join sc on (s.sno=(
select sno from sc where cno = 1 and sno in (select distinct sno from sc where cno = 2)));

28 字段约束,是将约束加在字段后面

非空约束 constraint xxx not null

唯一约束 unique

两个空值不认为是重复的

表级约束, constraint xxxx(名字随便起) unique(email[字段名],name[字段名]) {表示这两个字段的组合不能为空}

29 主键约束
primary key (唯一的不可重复的不可为空的)
外键约束
references 表名(字段)
写成表级约束
constraint xxx foreign key (字段名) references 外表名(外表字段)

如:create table stu(
id int,
name varchar(50) constraint aaa not null,
class1 number(6) ,
email varchar(30) ,
constraint stu_class_id foreign key (class1) references class(id),
constraint xxx unique(name,email)
);

create table class(
id number(6) primary key,
name varchar2(10)
)


31 修改表结构 alter

增加字段
alter table 表名 add(字段名,参数)
如:alter table stu add(school,varchar2(20));

删除字段
alter table 表名 drop(字段名)
如:alter table stu drop(school);

修改字段
alter table 表名 modify(字段名,参数)
如:alter table stu modify(email,varchar(50))


33 索引

一个表如果加了 “主键限制”,“唯一限制”,“组合限制”

oracle会自动生成索引

索引创建格式

create index xxx(索引名随便起,最好见名知义) on 表名(字段名)
如:create index index_stu_email on stu(email);

删除索引

drop index xxx;

显示数据库中有什么索引

select index_name from user_indexes;

第一范式-要有主键,列不可分,

第二范式-不能存在部分依赖,不是主键的字段不能部分依赖主键

第三范式-除了主键外的字段不能存在传递依赖


PL SQL显示
pl/sql 面向过程的sql 带有分支和循环的sql

匿名块 :没有名字的程序

PL/SQL分为四块

declare 定义变量(可有可无)
begin 程序从这里开始(必须)
exception 有异常时执行
end;(必须)

如:
set serveroutput on;(必须先执行这一命令,因为默认是OFF,如果是OFF的话,就不会输出)
begin
dbms_output.put_line('helloworld');
end;

set serveroutput on;

declare
v_name varchar2(20);
begin
v_name := 'myname';
dbms_output.put_line(v_name);
end;


declare
v_num number :=0;
begin
v_num := 2/v_num;
dbms_output.put_line(v_num);
exception
when others then
dbms_output.put_line('error');
end;


--变量声明的规则

1. 变量名不能够使用保留字,如from,select等
2. 第一个字符必须是字母
3. 变量名最多包含30个字符
4. 不要与数据库的表或者列同名
5. 每一行只能声明一个变量

--常用变量类型

1. binary_interger:整数,主要用来计数而不是用来表示字段类型
2. number:数字类型
3. char:定长字符串
4. varchar2:变长字符串
5. date:日期
6. long:长字符串,最长2GB
7. boolean:布尔类型,可以取值为true,false和null值


--变量声明
declare
v_temp number(1);
v_count binary_integer := 0;
v_sal number(7,2) := 4000.00;
v_date date := sysdate;
v_pi constant number(3,2) := 3.14;
v_valid boolean := false;
v_name varchar(20) not null := 'MyName';
begin
dbms_output.put_line('v_temp value:' || v_count);
end;
当变量声明为boolean类型时,该变量能不直接打印
如上面变量不能写成
dbms_output.put_line(v_valid);

--变量声明,使用%type属性
declare
v_empno number(4);
v_empno2 emp.empno%type;
v_empno3 v_empno2%type;
begin
dbms_output.put_line('Test');
end;
当使用“%type” 声明变量时,该变量变得灵活,会随着表的字段的修改而自动修改


--Table变量类型 Table复合变量(相当于java中的数组)
declare
type(关键字,说明是定义的新类型) type_table_emp_empno is table of emp.empno%type index by binary_integer;
v_empnos type_table_emp_empno;
begin
v_empnos(0) := 7369;
v_empnos(2) := 7839;
v_empnos(-1) := 9999;
dbms_output.put_line(v_empnos(-1));
end;

--Record变量类型 (record变量相当于java中的类)
declare
type type_record_dept is record
(
deptno dept.deptno%type,
dname dept.dname%type,
loc dept.loc%type
);
v_temp type_record_dept;
begin
v_temp.deptno := 50;
v_temp.dname := 'aaaa';
v_temp.loc := 'bj';
dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);
end;

--使用%rowtype声明record变量 (record变量相当于java中的类)可以随着表的改动自动更新变量
declare
v_temp dept%rowtype;
begin
v_temp.deptno := 50;
v_temp.dname := 'aaaa';
v_temp.loc := 'bj';
dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);
end;

--SQL语句的运用
在PL/SQL里面用select 必须加 “into”,且在select语句里面必须有且只能返回一条语句
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal into v_ename,v_sal from emp where empno = 789;
dbms_output.put_line(v_ename || ' ' || v_sal);
end;


declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal into v_ename,v_sal from emp where deptno = 10
dbms_output.put_line(v_ename || ' ' || v_sal);
end;

--ddl在PL/SQL中的运用

创建表

在PL/SQL中创建表时,前面必须加“execute immediate” ,然后后面的建表语句用单引号引上
如果在单引号中,又出现单引号,则内部单引号用 (‘’)代表(‘);
begin
execute immediate 'create table t (nnn varchar2(20) default ''aaa'')';
end;


--游标 cursor

declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
fetch c into v_emp;
dbms_output.put_line(v_emp.ename);
close c;
end;


declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
loop

fetch c into v_emp;
exit when (c%notfound);
dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;


--循环遍历
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
loop

fetch c into v_emp;
dbms_output.put_line(v_emp.ename);
exit when (c%notfound);

end loop;
close c;
end;

--IF语句

取出7369的薪水,如果 <1200 ,则输出‘low’,如果 <2000则输出‘middle’,否则'hign'

declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno = 7369;
if(v_sal < 1200) then
dbms_output.put_line('low');
elsif(v_sal <2000) then //elsif这里中间的E是没有的
dbms_output.put_line('middle');
else
dbms_output.put_line('hign');
end if;
end;

循环 PL/SQL里面的循环一定是以LOOP 开始,以END LOOP结束

下面这个相当于 DO WHILE
declare
i binary_integer := 1;
begin
loop
dbms_output.put_line(i);
i := i + 1;
exit when( i >= 11);
end loop;
end;


下面相当于while循环
declare
j binary_integer := 1;
begin
while j < 11 loop
dbms_output.put_line(i);
j := j + 1;
end loop;
end

--for循环
declare
cursor c is
select * from emp;
begin
for v_emp in c loop
dbms_output.put_line(v_emp.ename);
end loop;
end;


--带参数的游标

declare
cursor c(v_deptno emp.deptno%type, v_job emp.job%type)
is
select ename,sal from emp where deptno = v_deptno and job = v_job;
begin
for v_temp in c(30,'CLERK') loop
dbms_output.put_line(v_temp.ename);
end loop;
end;


--可更新的游标
declare
cursor c
is
select * from emp2 for update;
begin

for v_temp in c loop
if(v_temp.sal < 2000) then
update emp2 set sal = sal*2 where current of c;
elsif (v_temp.sal = 5000) then
delete form emp2 where current of c;
end if;
end loop;
commit;
end;


--存储过程
create or replace procedure p
is
--上面的替代declare,其他都一样
cursor c is
select * from emp2 for update;
begin
for v_emp in c loop
if (v_emp.deptno = 10) then
update emp2 set sal = sal + 10 where current of c;
elsif (v_emp.deptno = 20)
update emp2 set sal = sal + 20 where current of c;
else
update emp2 set sal = sal + 50 where current of c;
end if;
end loop;
commit;
end;

--执行存储过程
exec p;
另外一种执行方式
begin
p;
end;


--带参数的存储过程
create or replace procedure p
(v_a in number, v_b number, v_ret out number,v_temp in out number )
is

begin
if(v_a > v_b) then
v_ret := v_a;
else
v_ret := v_b;
end if;
v_temp := v_temp + 1;
end;


declare
v_a number := 3;
v_b number := 4;
v_ret number;
v_temp number := 5;
begin
p(v_a,v_b,v_ret,v_temp);
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;

--函数
create or replace function sax_tax
(v_sal number)
return number
is
begin
if(v_sal < 2000) then
return 0.10;
elsif(v_sal < 2750) then
return 0.15;
else
return 0.20;
end if;
end;

--执行函数
select lower(ename), sal_tax(sal) from emp;


--触发器 当做一个件事的时候,一触动就会触发另一事件
create table emp2_log
(
uname varchar2(20),
action varchar2(10),
atime date
);

create or replace trigger trig
after insert or delete or update on emp2 for each row
begin
if inserting then
insert into emp2_log values (USER, 'insert',sysdate);
elsif updateing then
insert into emp2_log values (USER, 'update',sysdate);
elsif deleting then
insert into emp2_log values (USER, 'delete',sysdate);
end if;
end;

--触发器用于更新关联

create or replace trigger trig
after update on dept
for each row
begin
update emp set deptno = :NEW.deptno where deptno = :OLD.deptno;
end;

应用
update dept set deptno = 99 where deptno = 10;--NEW.deptno:99 OLD.deptno:10


--树状结构的存储与展示
drop talbe article;

create table article
(
id number primary key,
cont varchar2(4000),
pid number,
isleaf number(1), --0 代表非叶子节点,1代表叶子节点
alevel number(2)
);

insert into article values (1,'蚂蚁大战大象',0,0,0);
insert into article values (2,'大象被打趴下了',1,0,1);
insert into article values (3,'蚂蚁也不好过',2,1,2);
insert into article values (4,'瞎说',2,0,2);
insert into article values (5,'没有瞎说',4,1,3);
insert into article values (6,'怎么可能',1,0,1);
insert into article values (7,'怎么没有可能',6,1,2);
insert into article values (8,'可能性是很大的',6,1,2);
insert into article values (9,'大象进医院了',2,0,2);
insert into article values (10,'护士是蚂蚁',9,1,3);

蚂蚁大战大象
大象被打趴下了
蚂蚁也不好过
瞎说
没有瞎说
大象进医院了
护士是蚂蚁
怎么可能
怎么没有可能
可能性是很大的


create or replace procedure p(v_pid article.pid%type, v_level binary_integer)
is
cursor c is select * from article where pid = v_pid;
v_preStr varchar2(1024) := '';
begin
for i in 1..v_level loop
v_preStr := v_preStr || ' |';
end loop;

for v_article in c loop
dbms_output.put_line(v_preStr || v_article.cont);
if(v_article.isleaf=0) then
p(v_article.id,v_level + 1);
end if;
end loop;
end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值