Oracle数据库
服务端操作sql语句
登录sql
sqlplus
超级管理员账号密码
账号:system 密码:123456
修改账号密码
alter user scott identified by 123456 account unlock;
普通登录
账号:scott 密码:123456
增删改查
select * from student for update;
--oracle中 增删改查一定要记得提交
insert into student values(6,'刘雄',19)
commit;
分页查询
select * from(select student.*,rownum rn from student) s where s.rn>=3 and s.rn<=6
select * from(select s.*,rownum rn from (select * from (select eid ,ename,ebrithday,eaddress,dname,dsalary from Employee join Dept on Employee.did=Dept.did order by dsalary desc)) s
) v where v.rn>3
数据作业
--1.查询所有员工的基本信息 按照工号排序
select * from Employee join Dept on Employee.did=Dept.did order by eid asc
--2.查询财务部的岗位工资
select dsalary from Employee join Dept on Employee.did=Dept.did where dname='财务部'
--3.查询财务部下有那些员工
select * from Employee join Dept on Employee.did=Dept.did where dname='财务部'
--4.查询比张三工资高的员工信息
select * from Employee join Dept on Employee.did=Dept.did where dsalary >(select dsalary from Employee join Dept on Employee.did=Dept.did where ename='张三')
--5.查询每个部门有多少员工 从多到少排列
select count(*) from Employee join Dept on Employee.did=Dept.did group by dname order by dname
--6.查询本公司一年总共支出多少工资
select sum(dsalary)*12 from Employee join Dept on Employee.did=Dept.did order by eid asc
--7.查询公司薪资最高的前三名
select * from (select eid,ename,ebrithday,eaddress,dname,dsalary,rownum from Employee join Dept on Employee.did=Dept.did order by dsalary desc
) where rownum <= 3;
--8.查询公司薪资最高的第5到8名
select * from(select s.*,rownum rn from (select * from (select eid ,ename,ebrithday,eaddress,dname,dsalary from Employee join Dept on Employee.did=Dept.did order by dsalary desc)) s
) v where v.rn>3
--9.查询年龄比李四大的员工信息
select * from Employee join Dept on Employee.did=Dept.did where ebrithday < (select ebrithday from Employee join Dept on Employee.did=Dept.did where ename='李四')
--10.查询今年年满30岁的员工信息
select * from (select s.*,TRUNC ( MONTHS_BETWEEN (SYSDATE, ebrithday)/12) as a from (select * from Employee join Dept on Employee.did=Dept.did ) s
) r
where r.a>30
第二种方法
select e.*,d.dname,d.dsalary from employee e join dept d on e.did=d.did where (select sysdate from dual)-e.ebrithday>=30*365
面试题 要掌握
--(1)查询课程编号为“001”的课程比“002”的课程成绩高的所有学生的学号?
select * from student where sid in (select a.sid from (select * from score where cid='1')a,(select * from score where cid='2')b
where a.score>b.score)
--(2)查询平均成绩大于60分的学生的学号和平均成绩?
select * from(select avg(score) a,student.sid from student join score on student.sid=score.sid
group by student.sid ) s where s.a>60
--(3)查询所有学生的学号、姓名、选课数、总成绩?
select count(course.cid),sum(score.score),student.sname from student ,score ,course,teacher where student.sid=score.sid and score.cid=course.cid and course.tid=teacher.tid
group by student.sname
--(4)查询姓“悟”的老师的个数?
select count(*) from teacher where tname like '悟%'
--(5)查询没学过“悟空”老师课的学生的学号、姓名?
select * from student where sid not in(select sid from score where cid in (select cid from course where tid=(select tid from teacher where tname='悟空'))
)
1.表空间
ORCL
表空间主要是为了整理 分类数据
创建表空间
--创建表空间
--真实存在 所以要指定路径
--分配存储大小
create tablespace tp _a
datafile 'd:\TablespaceShenjian\tp_a01.dbf' size 60M;
删除表空间
--删除
drop tablespace tp_a
including contents;
2.创建用户
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vlPTvkkM-1647479815864)(C:\Users\shenjian\AppData\Roaming\Typora\typora-user-images\image-20220216144804328.png)]
填写:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qg2ZvcHl-1647479815865)(C:\Users\shenjian\AppData\Roaming\Typora\typora-user-images\image-20220216144131837.png)]
赋予权限
grant connect,resource to test1;
赋予具体实体的操作权限
--赋予所有权限
grant all on scott.student to test1;
--查询权限
grant select on scott.student to test1;
--修改权限
grant update on scott.student to test1;
--删除权限
grant delete on scott.student to test1;
--赋予权限之后查询
grant all on scott.student to test1;
3.序列
什么是序列?
是一个能够自增长的 独立存在的一个东西
创建序列 序列是独立存在的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UCM5R89G-1647479815866)(C:\Users\shenjian\AppData\Roaming\Typora\typora-user-images\image-20220216145945497.png)]
一般nextval和currval用于序列sequence中,
-通过nextval和currval进行调用
nextval:每次获得不同的sequence值,根据increment(增量),序列值增加
currval:获得当前指向的sequence值(只执行currval的话,不会因执行次数而改变)
·--创建序列 是独立存在的
--select seq_a.currval from dual;
--select seq_a.nextval from dual;
--insert into student values(seq_a.nextval,'小剑',11,'女');
4.同义词
有什么用?
可以使用取的名字去使用他查询
创建同义词
右键new
Synonyms
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tpMQlyHW-1647479815866)(C:\Users\shenjian\AppData\Roaming\Typora\typora-user-images\image-20220216152946330.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bOmyeJY9-1647479815866)(C:\Users\shenjian\AppData\Roaming\Typora\typora-user-images\image-20220216152615260.png)]
查询
select * from s
5.索引
--索引 一定要建立在大数据量的基础上才有用
--Oracle 的索引 位图索引 大写函数索引 主键索引 唯一索引 反向建索引
主键索引,只能创建到主键索引上,创建主键就出来了,不能为空,唯一索引需要主动创建,可以为空 ,可以创建到任何列,但是不能重复
--唯一索引
create unique index index_u_age
on student(sid);
--反向键索引
create index index_u_age
on student(sid) reverse;
--创建位图索引
create bitmap index index_u_age on student(sid) ;
--针对函数建立索引
create index index_u_age on student(UPPER(sid));
--删除索引
drop index index_u_age
6.表分区
PL/Sql编程
什么是 PL/Sql编程?
不仅仅只是写增删改查 写定义变量、赋值、判断循环
declare //声明 定义的区域
begin //开始书写代码的区域
end;
declare
v_yuwen number(4);
v_shuxue number(4);
v_Englis number(4);
v_avg number(4);
begin
--直接给变量复制,=在数据库中是比较的意思 所以需要加: 表示他是一个变量
v_yuwen:=80;
v_shuxue:=60;
v_Englis:=60;
v_avg:=avg(v_yuwen+v_shuxue+v_Englis);
Dbms_Output.put_line('张唉干的平均成绩是:'||v_avg);
end;
--当你想得到某个表的数据时 你并不知道哪一列的数据类型你就可以使用表名.列名为数据类型
declare
v_a student.sname%TYPE;
v_b student.sage%TYPE;
c_c constant number(5):=100;--C开头定义的是常量
begin
--直接给变量赋值
select sname,sage
into v_a,v_b
from student where sid=21;
Dbms_Output.put_line('查找赋值:'||v_a||v_b);
end;
if分支
--当你想得到某个表的数据时 你并不知道哪一列的数据类型你就可以使用表名.列名为数据类型
declare
v_b student.sage%TYPE;
begin
select sage
into v_b
from student where sid=21;
if v_b<18 then
DBMS_OUTPUT.put_line('未成年!');
elseif v_b<100 then
DBMS_OUTPUT.put_line('大老年!');
elseif v_b<80 then
DBMS_OUTPUT.put_line('老年!');
end if;
end;
while 循环
--当你想得到某个表的数据时 你并不知道哪一列的数据类型你就可以使用表名.列名为数据类型
declare
v_a number(4):=200;
begin
loop
dbms_output.put_line('今天天气不错');
v_a:=v_a+1;
insert into student values(v_a,'小白',11,'男');
exit when v_a=210;
commit;
end loop;
end;
swich循环
--当你想得到某个表的数据时 你并不知道哪一列的数据类型你就可以使用表名.列名为数据类型
declare
v_a number(11):=11;
begin
case
when v_a<10 then dbms_output.put_line('小于10');
when v_a<20 then dbms_output.put_line('小于20');
when v_a<30 then dbms_output.put_line('小于30');
when v_a<40 then dbms_output.put_line('小于40');
end case;
commit;
end;
游标
游标有啥用?
用来存储多种结果集
--当你想得到某个表的数据时 你并不知道哪一列的数据类型你就可以使用表名.列名为数据类型
declare
--定义游标
cursor cursor_a is
select * from student;
v_sid student.sid%TYPE;
v_sname student.sname%TYPE;
v_age student.sage%TYPE;
v_ssex student.ssex%TYPE;
begin
--打开游标
open cursor_a;
--提取游标
--使用游标
loop
fetch cursor_a into v_sid,v_sname,v_age,v_ssex;
exit when cursor_a%notfound;
Dbms_Output.put_line('6666:'||v_sname||v_sid||v_age||v_ssex);
end loop;
--关闭游标
close cursor_a;
end;
--1.计算所有员工实际发放的工资 逐一输出
declare
--定义游标
cursor cursor_Work is
select * from work;
v_wid work.wid%TYPE;
v_wname work.wname%TYPE;
v_waddress work.waddress%TYPE;
v_wage work.wage%TYPE;
v_wmoney work.wmoney%TYPE;
v_flag work.flag%TYPE;
v_wdate work.wdate%TYPE;
v_jdate work.jdate%TYPE;
begin
--打开游标
open cursor_work;
--提取游标
--使用游标
loop
fetch cursor_work into v_wid,v_wname,v_waddress,v_wage,v_wmoney,v_flag,v_wdate,v_jdate;
exit when cursor_work%notfound;
if v_flag<1 then
Dbms_Output.put_line('您的实际工资是:'||v_wmoney*0.8);
else
Dbms_Output.put_line('您的实际工资是:'||v_wmoney);
end if;
end loop;
--关闭游标
close cursor_work;
end;
存储过程
什么是存储过程?
存储过程相当于封装了一个方法
--存储过程相当于封装了一个方法
--先声明
create procedure add_student(
sid student.sid%TYPE,
sname student.sname%TYPE,
sage student.sage%TYPE,
ssex student.ssex%TYPE,
out_flag out number --out代表存储过程的返回值
)
is
begin
insert into student values (sid,sname,sage,ssex);
out_flag:=1;
commit;
end;
--调用存储过程
declare
flag number;
begin
add_student(1114,'小红',23,'女',flag);
dbms_output.put_line(flag);
end;
小练习
elect wid,wname,waddress,wage,wmoney,flag,wdate, TRUNC(MONTHS_BETWEEN (SYSDATE,jdate)/12)as a from work;
select * from work
--1.计算所有员工实际发放的工资 逐一输出
declare
--定义游标
cursor cursor_Work is
select * from work;
v_wid work.wid%TYPE;
v_wname work.wname%TYPE;
v_waddress work.waddress%TYPE;
v_wage work.wage%TYPE;
v_wmoney work.wmoney%TYPE;
v_flag work.flag%TYPE;
v_wdate work.wdate%TYPE;
v_jdate work.jdate%TYPE;
begin
--打开游标
open cursor_work;
--提取游标
--使用游标
loop
fetch cursor_work into v_wid,v_wname,v_waddress,v_wage,v_wmoney,v_flag,v_wdate,v_jdate;
exit when cursor_work%notfound;
if v_flag<1 then
Dbms_Output.put_line('您的实际工资是:'||v_wmoney*0.8);
else
Dbms_Output.put_line('您的实际工资是:'||v_wmoney);
end if;
end loop;
--关闭游标
close cursor_work;
end;
--2.给转正的员工 工资加200 给转正了的并且转正年份大于3年的加400 给转正了的并且转正年限大于5年的加1000
declare
--定义游标
cursor cursor_Work is
select * from work;
v_wid work.wid%TYPE;
v_wname work.wname%TYPE;
v_waddress work.waddress%TYPE;
v_wage work.wage%TYPE;
v_wmoney work.wmoney%TYPE;
v_flag work.flag%TYPE;
v_wdate work.wdate%TYPE;
v_jdate work.jdate%TYPE;
begin
--打开游标
open cursor_work;
--提取游标
--使用游标
loop
fetch cursor_work into v_wid,v_wname,v_waddress,v_wage,v_wmoney,v_flag,v_wdate,v_jdate;
exit when cursor_work%notfound;
if v_flag>0 and TRUNC(MONTHS_BETWEEN (SYSDATE,v_jdate)/12)>=5 then
Dbms_Output.put_line('您的实际工资是:'||(v_wmoney+1600));
elsif v_flag>0 and TRUNC(MONTHS_BETWEEN (SYSDATE,v_jdate)/12)>=3 then
Dbms_Output.put_line('您的实际工资是:'||(v_wmoney+600));
else
Dbms_Output.put_line('您的实际工资是:'||v_wmoney*0.8);
end if;
end loop;
--关闭游标
close cursor_work;
end;
--3.开除在公司工作一年还未转正的
declare
flag number;
--定义游标
cursor cursor_Work is
select * from work;
v_wid work.wid%TYPE;
v_wname work.wname%TYPE;
v_waddress work.waddress%TYPE;
v_wage work.wage%TYPE;
v_wmoney work.wmoney%TYPE;
v_flag work.flag%TYPE;
v_wdate work.wdate%TYPE;
v_jdate work.jdate%TYPE;
begin
--打开游标
open cursor_work;
--提取游标
--使用游标
loop
fetch cursor_work into v_wid,v_wname,v_waddress,v_wage,v_wmoney,v_flag,v_wdate,v_jdate;
exit when cursor_work%notfound;
if v_flag=0 and TRUNC(MONTHS_BETWEEN (SYSDATE,v_jdate)/12)>=1 then
delete from work where wid=v_wid;
Dbms_Output.put_line('删除成功!');
else
Dbms_Output.put_line('');
end if;
end loop;
--关闭游标
close cursor_work;
end;
--4.创建一个储存过程:能够根据输入的姓名及关键字 就能查出并返回这个人的实发工资
--存储过程相当于封装了一个方法
--先声明
create procedure add_workss(
a_wname work.wname%TYPE,
out_flag out number
)
is
begin
select wmoney into out_flag from work where wname like concat(a_wname,'%');
end;
--调用存储过程
declare
flag number;
begin
add_workss('申',flag);
dbms_output.put_line(flag);
end;
--5.创建一个存储过程:能够根据输入的年份以及年龄 查询返回对应人员跟实发工资
--存储过程相当于封装了一个方法
--先声明
create procedure add_workss(
a_wage work.wage%TYPE,
a_wdate work.wdate%TYPE,
out_flag out number, --out代表存储过程的返回值
out_name out nvarchar2
)
is
begin
select wmoney,wname into out_flag,out_name from work where wdate=a_wdate and wage=a_wage;
commit;
end;
--调用存储过程
declare
flag number;
name varchar2(10);
begin
add_workss(17,to_date('2022-2-18','yyyy/mm/ss'),flag,name);
dbms_output.put_line(flag);
end;