数据库:存储和处理数据,如图片、视频、个人基本信息等等都是数据
常见的数据库产品:Sql Server、Mysql、Oracle、Db2,我们学习Oracle数据库
安装Oracle数据库
1)、电脑硬件要求(大部分电脑硬件配置都符合要求) 2)、软件要求(如网络、端口等等)
3)、Oracle不能重复安装,在安装之前,首先确认电脑中是否已经安装了Oracle,若已经安装,则不需要再安装
4)、在XP系统中,安装Oracle10g,若是位系统,则需要安装Oracle 位版本;若是win7以上系统,建议安装Oracle 11g
5)、Oracle的安装程序不能放在中文目录下
6)、操作系统是Home版本(是经过压缩的,很多功能都没有),直接将Home版本的操作系统换成旗舰版或专业版
7)、在安装Oracle数据库时,建议用administrator账号登陆操作系统
服务端(选择性掌握):
a)、安装数据库服务端软件 b)、配置监听程序
c)、创建数据库(可以创建多个数据库)
参考\"Oracle10g的安装.exe\"、\"window下Oracle安装与卸载.doc\"
客户端:
a)、安装数据库客户端软件
b)、配置本地服务(即tns文件),用于远程连接数据库,需要的配置信息有:(必须掌握) 数据库服务器的IP(或主机名) 全局数据库名称(也即sid) 监听端口(默认是1521)
登陆数据库还需要用户名和密码 参考\"客户端远程连接服务器.exe\" */ /*
数据库对象:用户、角色、表、视图、表空间、存储过程、触发器、同义词、函数、包...... 选择My objects,只显示当前用户所拥有的对象
最关心的对象是:表(相当于一个Excel中的sheet页) */
/*SQL语句:用于操作数据
DDL:数据库定义语句(create、alter、drop) DCL:数据库控制语句(grant、revoke等等) */
/*新增用户
create user 用户名 identified by 登陆密码; */
create user liangxianfu identified by liangxianfu;
/*授权
grant 角色1,角色2...角色N to 用户名;
角色:是权限的集合,里面包含了很多权限,Oracle中内置了很多角色。 一个用户可以拥有多个角色,一个角色有很多权限。 */
grant connect,resource,dba to liangxianfu;
/*回收权限
revoke 角色1,角色2,...角色N from 用户名; */
revoke resource,dba from liangxianfu;
/*修改用户密码
alter user 用户名 identified by 密码; */
alter user liangxianfu identified by liangxianfu02;
/*锁定/解锁用户
alter user 用户名 account lock/unlock; */
alter user liangxianfu account lock; alter user liangxianfu account unlock;
alter user liangxianfu account unlock identified by liangxianfu;
/*删除用户
drop user 用户名; */
drop user liangxianfu;
--创建自己的账号,设置密码,用自己的账号登陆。
/*创建表
create table 表名(
列名 number [constraint 主键名字 primary key],
列名 char(长度) [constraint 唯一性约束的名字 unique],
列名 varchar2(长度) [constraint 检查约束的名字 check(条件)], 列名 char(长度) [not null] [default 默认值] 列名 date, ...,
列名N 数据类型 );
命名规则:字符、数字、下划线(_)组成,不要以数字开头。 number:数字类型
number(3,2),小数是2位,整数是1位,总共是3位 字符串:
char(长度):定长,char(12),总长度是12个字节,如果实际存储6个字节,该列仍然占用12个字节
varchar2(长度):可变长,varchar2(12),总长度是12个字节,如果实际存储6个字节,该列占用6个字节
字节:是由二进制代码(即0和1组成),1个字节 = 8个二进制位
字符:字节经过一定的编码方式组成字符,UTF-8是国际通用字符集,精通8国语言翻译官 若数据库采用UTF-8编码,那么一个中文字符占用3个字节,数据和引文字符是占用1个字节
date:日期
约束:就是一种条件
主键:相当于身份证号,通过主键只能找到一条数据,建议在一张表中,至少一个主键对象,且只能有一个主键对象。
主键属于表对象。有名字,若没有指定名字,则由Oracle数据库了自动分配一个唯一的名字。 外键:
唯一:不能重复,属于表对象,有名字。
非空:在默认情况下,列是允许为空的,not null | null 检查:检测值是否满足指定条件,属于表对象,有名字。
在实际工作中,创建表时不会设置太多的约束。
默认值:当列没有填写值的时候,则取默认值。 */
create table t_student( id number,
name varchar2(50), sex char(12), birthday date );
create table t_class(
classid number constraint pk_class_id primary key, classname varchar2(50) );
create table t_student(
id number constraint pk_student_id primary key,
name varchar2(50) constraint un_student_name unique,
sex char(12) constraint ck_stu_sex check(sex = '男' or sex = '女'), birthday date not null,
classid number constraint fk_stu_classid references t_class(classid) );
comment on table t_student is '学员基本信息表'; comment on column t_student.name is '学员姓名';
/*修改表结构 alter table 表名
modify 列名 数据类型 [各种约束]; */
alter table t_student
modify name char(50) not null;
alter table t_student
drop constraint un_student_name;
/*修改列名 alter table 表名
rename column 列名 to 新名字; */
alter table t_student
rename column sex to ssex;
/*删除列
alter table 表名 drop column 列名; */
alter table t_student drop column sex;
/*新增列
alter table 表名
add 列名 数据类型 [各种约束] */
alter table t_student
add sex char(12) default '女' not null check(sex in ('男','女'));
--sysdate:获取系统当前时间,格式是:年月日时分秒,是date类型 alter table t_student
modify birthday default sysdate;
/*删除表
drop table 表名; */
drop table t_student;
/*DML语句:数据操作语句
新增、修改、删除、查询(整个Oracle课程的重点) dml语句一定要满足各种约束
事务:简单理解就是做一件事情的过程,事务有最终的结果:成功或失败。 成功:事务所产生的结果会永久反馈到数据库中。
失败:事务所产生的结果会丢弃,不会反馈到数据库中。 一旦开启事务,就必须结束事物,结束事物的方式有两种: commit:事务执行成功,结果会永久反馈到数据库中。 rollback:事务的结果被丢弃,不会保存到数据库中。
可以由多条dml语句组成一个事物 */
/*新增数据
insert into 表名(列1,列2,...,列N) values(值1,值2,...,值N); commit | rollback;
用单引号引起是字符串
用双引号引起是别名(即名字) */
insert into t_class (classid, classname) values (1, '测试一班'); commit;
--发起一个事务
insert into t_class (classid, classname) values (2, '测试二班'); insert into t_class (classid, classname) values (3, '测试三班'); insert into t_class (classid, classname) values (4, '测试四班'); commit;
/*修改数据 update 表名 set 列1 = 值1, 列2 = 值2, ...,
列N = 值N [where过滤条件];
commit | rollback; */
update t_class set classname = '测试班'; commit;
insert into t_class (classid, classname) values (5, '测试五班'); update t_class set classname = '测试班'; commit;
/*删除
delete [ from ] 表名 [ where过滤条件 ]; commit | rollback; */
delete from t_class; commit;
--思考以下几条sql语句组成几个事物,最终的结果是怎样的? insert into t_class (classid, classname) values (5, '测试五班'); update t_class set classname = '测试班'; delete from t_class; rollback;
/*截断表
truncate table 表名; truncate不会发起事务,如果表中的列被另外一张表引用(外键),则不能对该表进行truncate,属于ddl语句,不能有where过滤条件。
delete会发起事务,属于dml语句。可以有where过滤条件
truncate和delete都可以删除表中的所有数据,truncate效率要高。 */
truncate table t_class;
alter table t_student
drop constraint fk_stu_classid;
/*查询
select 列1,列2,...,列N from 表 [where过滤] [group by 分组] [having过滤] [order by排序]; */
--查询指定列
select sname, sex from student;
select birthday, classid, studentid, sname, sex from student; select * from student;
--where过滤行,涉及到比较
-->、<、<>或!=、=等等比较运算符,比较运算符两端的数据类型要保持一致。 select sname, sex from student where sex = '女';
select sname, sex from student
where sex <> '女';
select sname, sex, classid from student where classid = 6; select sname, sex, classid from student where classid <> 6;
--查询2013-06-20之后出生的学员信息
--to_date():将字符串日期转换成date类型的日期 --to_date(字符串日期,格式字符串)
--格式字符串:yyyy-mm-dd HH24:mi:ss、yyyy-mm/dd --trunc()截断日期,保留年月日,返回date类型
select * from student where birthday > to_date('20-6/2013', 'dd-mm/yyyy'); select * from student where birthday >= to_date('21-6/2013', 'dd-mm/yyyy');
select * from student where birthday > to_date('20-6/2013 23:59:59', 'dd-mm/yyyy HH24:mi:ss'); select * from student where trunc(birthday) > to_date('20-6/2013', 'dd-mm/yyyy');
--多条件查询
--and(且):会减少查询结果的数据量 --or(或):会增加查询结果的数据量 select *
from student
where sex = '女' and classid = 6; select *
from student where sex = '女' or classid = 6;
-->all、>any、>=all、>=any、<=all、<=any
-->all:是and的关系,会减少查询结果的数据量,比最大的值要大 -->any:是or的关系,会增加查询结果的数据量,比最小值要大 select * from student where studentid > all(10, 20);
select * from student where studentid > 10 and studentid > 20; select * from student where studentid > 20;
select * from student where studentid > any(10, 20);
select * from student where studentid > 10 or studentid > 20; select * from student where studentid > 10;
--in:在一组值当中,or的关系
--not in:不在一组值当中,and的关系
select * from student where studentid in(10, 20,30); select *
from student
where studentid = 10
or studentid = 20 or studentid = 30;
select * from student where studentid not in(10, 20,30);
select * from student where studentid <> 10 and studentid <> 20 and studentid != 30;
--between...and..在某个返回之内,包括端点
select * from student where studentid between 10 and 20;
select * from student where studentid >= 10 and studentid <= 20;
--以下两条sql是否等同?
select * from student where studentid between 10 and 20;
select * from student where studentid > 10 and studentid <= 20;
/*模糊查询 like
%匹配多个 _只匹配一个 */
select * from student where sname like '刘%'; select * from student where sname like '刘__';
/*查询
select 列1,列2,...,列N from 表1,表2,...,表N [where过滤] [group by 分组] [having过滤] [order by排序];
select 列1,列2,...,列N
from 表1 inner join 表2 on 关联条件1 ...
inner join 表N on 关联条件N [where过滤] [group by 分组] [having过滤] [order by排序]; */
select * from student; select * from class;
--产生笛卡尔积
select * from student, class;
--选择了能够体现表关系的列作为关联条件 --内连接
select * from student st, class cl where st.classid = cl.classid;
--等效于
select * from student st inner join class cl on st.classid = cl.classid;
--左连接:满足关联条件的数据取出来,左表中不满足关联条件的数据也取出来(右表的数据取null)
--在left join左边的表是左表,右边的表是右表
select * from class cl left join student st on st.classid = cl.classid; select * from student st left join class cl on st.classid = cl.classid;
--造数据
insert into student values(999,'999感冒灵','女',sysdate,999); insert into class values(888,'888财付通'); commit;
--右连接:满足关联条件的数据取出来,右表中不满足关联条件的数据也取出来(左表的数据取null)
--right join左边的表是左表,右边的表是右表
select * from class cl right join student st on st.classid = cl.classid; select * from student st right join class cl on st.classid = cl.classid;
--查询527班所有学员
select st.sname, st.sex, cl.classname from class cl, student st
where cl.classid = st.classid and cl.classname = '527'; --等效
select st.sname, st.sex, cl.classname from class cl
inner join student st
on cl.classid = st.classid where cl.classname = '527';
--查询527班所有学员Oracle课程的分数,显示姓名、性别、班级名称、分数 --lower()将字符串转换成小写 --upper()将字符串转换成大写
select st.sname, st.sex, cl.classname, sc.score from class cl, course co, stscore sc, student st where cl.classid = st.classid
and st.studentid = sc.studentid and co.courseid = sc.courseid and cl.classname = '527'
and upper(co.cname) = 'ORACLE'; --lower(co.cname) = 'oracle' --等效
select st.sname, st.sex, cl.classname, sc.score from class cl
inner join student st
on cl.classid = st.classid inner join stscore sc
on st.studentid = sc.studentid inner join course co
on co.courseid = sc.courseid where cl.classname = '527'
and upper(co.cname) = 'ORACLE';
--查询所有考Linux课程的学员信息,显示:姓名、性别、班级名称 select st.sname, st.sex, cl.classname, co.cname, sc.score from course co, student st, class cl, stscore sc where cl.classid = st.classid
and st.studentid = sc.studentid and co.courseid = sc.courseid and lower(co.cname) = 'linux';
/*分组查询
聚合函数:将多个值合并成一个值 sum():求和
max():求最大值 min():求最小值 avg():求平均值 count():求总记录数
聚合函数是可以单独使用的,并不说用聚合函数,就一定要用group by分组。 聚合函数会忽略掉null值 */
select * from student;
--思考以下sql?
select * from student st group by st.sex; select st.sex from student st group by st.sex;
select st.studentid, st.sex from student st group by st.sex; select st.studentid from student st group by st.sex;
--改进
select st.sex, count(st.studentid) \"总人数\" from student st group by st.sex;
--查询每门课程的总分、最高分、最低分、平均分, --显示:课程名称、总分、最高分、最低分、平均分。
select * from course co, stscore sc where co.courseid = sc.courseid;
select co.cname, sum(sc.score), avg(sc.score), max(sc.score), min(sc.score) from course co, stscore sc where co.courseid = sc.courseid group by co.cname; --改进
select co.courseid, max(co.cname), sum(sc.score), avg(sc.score), max(sc.score), min(sc.score)
from course co, stscore sc where co.courseid = sc.courseid group by co.courseid;
--查询826班每门课程的总分、平均分、最高分、最低分, --显示:课程名称、总分、最高分、最低分、平均分。 --步骤一:查找所有需要的数据
select *
from class cl, stscore sc, course co, student st where sc.courseid = co.courseid and st.classid = cl.classid
and st.studentid = sc.studentid and cl.classname = '826';
--round():四舍五入函数 select co.courseid,
max(co.cname), sum(sc.score),
round(avg(sc.score), 1), max(sc.score), min(sc.score)
from class cl, stscore sc, course co, student st where sc.courseid = co.courseid and st.classid = cl.classid
and st.studentid = sc.studentid and cl.classname = '826' group by co.courseid;
--having:是数据分组聚合之后的过滤,只能紧跟group by,没有group by就没有having过滤(用where过滤)
--where:是数据分组聚合之前的过滤
--查询826班oracle课程的总分、平均分、最高分、最低分 select co.courseid,
max(co.cname), sum(sc.score),
round(avg(sc.score), 1), max(sc.score), min(sc.score)
from class cl, stscore sc, course co, student st where sc.courseid = co.courseid and st.classid = cl.classid
and st.studentid = sc.studentid and cl.classname = '826' group by co.courseid
having lower(max(co.cname)) = 'oracle';
--方法二:在分组之前进行过滤 select min(co.cname), sum(sc.score),
round(avg(sc.score), 1),
max(sc.score), min(sc.score)
from class cl, stscore sc, course co, student st where sc.courseid = co.courseid and st.classid = cl.classid
and st.studentid = sc.studentid and cl.classname = '826'
and lower(co.cname) = 'oracle';
--查询每个学员的总分、平均分、最高分、最低分 --order by默认是升序排序(asc),降序排序是desc select min(st.sname), sum(sc.score),
round(avg(sc.score), 1), max(sc.score), min(sc.score)
from student st, stscore sc
where st.studentid = sc.studentid group by st.studentid
order by sum(sc.score) desc;
--查询每个学员的总分、平均分、最高分、最低分,只显示总分在200分以上的学员 select min(st.sname), sum(sc.score),
round(avg(sc.score), 1), max(sc.score), min(sc.score)
from student st, stscore sc
where st.studentid = sc.studentid -- and st.sname like '刘%' group by st.studentid
having sum(sc.score) > 200 --and min(st.sname) like '刘%' order by sum(sc.score) desc;
--查询每个班级每门课程的总分、平均分、最高分、最低分 select *
from class cl, stscore sc, course co, student st where sc.courseid = co.courseid and st.classid = cl.classid
and st.studentid = sc.studentid;
--多个列分组
select max(cl.classname), min(co.cname),
sum(sc.score),
round(avg(sc.score), 1), max(sc.score), min(sc.score)
from class cl, stscore sc, course co, student st where sc.courseid = co.courseid and st.classid = cl.classid
and st.studentid = sc.studentid group by cl.classid, co.courseid order by max(cl.classname);
/*null值的处理
null值比较只有一个结果:false null <> '826' false null = '826' false null = null false
方式一: is null is not null 方式二:
nvl(列,默认值):当列的值为null时,则返回\"默认值\",当列的值不为null时,返回列本身的值。 */
insert into class(classid) values(7); commit;
select * from class where classname = '826'; select * from class where classname <> '826'; select * from class where classname = null ; select * from class where classname is null ; select * from class where classname is not null ;
select * from class where nvl(classname, '826') = '826';
---聚合函数会忽略null值
--若在聚合函数中使用*号统配符时,则不会忽略null值,如count(*)就不会忽略null值 select max(st.sname), sum(sc.score),
round(avg(sc.score), 1), max(sc.score), min(sc.score),
count(*) \"不忽略null\ count(sc.score) \"忽略null\"
from student st, stscore sc
where st.studentid = sc.studentid -- and sc.score is not null group by st.studentid;
/*子查询
用一条sql代替某个值,或作为中间临时表,或作为查询的列。 */
select * from student where classid = 6;
select classid from class where classname < '826';
--查询826班所有的学员 select *
from student
where classid = (select classid from class where classname = '826');
--单行子查询运算符:>、<、<>或!=、=
--多行子查询运算符:>all、>any、>=all、>=any、<=all、<=any、in、not in --思考以下sql语句,理解子查询? select *
from student
where classid = (select classid from class);
select * from student where classid in (select classid from class);
select * from student where classid in (select classid,classname from class); /*
select 列1,列2,...,列N
from 结果集1,结果集2,...,结果集N [where过滤] [group by 分组] [having过滤] [order by排序]; */
--查询每个班级中人数信息,显示:总人数、男生人数、女生人数 select a.total \"总人数\男生人数\女生人数\" from (select st.classid, count(st.studentid) total from student st group by st.classid) a,
(select st.classid, count(st.studentid) t_boy from student st where st.sex = '男' group by st.classid) b
where a.classid = b.classid;
--查询学员人数信息,显示:总人数、男生人数、女生人数 select count(st.studentid) from student st;
select count(st.studentid) from student st where st.sex = '男';
select a.total, b.t_boy, c.tt
from (select count(st.studentid) total from student st) a,
(select count(st.studentid) t_boy from student st where st.sex = '男') b, (select count(st.studentid) tt from student st where st.sex = '女') c;
select t.total \"总人数\男生人数\女生人数\" from (select count(st1.studentid) total,
min((select count(st.studentid) t_boy from student st
where st.sex = '男')) t_boy from student st1) t;
/*伪列: 不是用ddl语句操作的列
rowid:是一个真实存在的值,即数据的物理位置值,
根据rowid查找数据的效率是最高的(我们所发出的查询语句,oracle首先找到数据的rowid, 然后根据rowid到数据文件中唯一定位数据)
如果查询中指定了一个无效的rowid,则查询会报错,因为rowid不存在,即在数据文件中不存在这样的数据。
rowid具备唯一性,属于表
rownum:Oracle个结果集增加的一个列,先有结果集,才能有rownum,有多少个结果集, 就有多少个rownum,没有结果集就没有rownum,他们是相互的,不属于表。 */
select * from class cl where cl.classid = 1;
--指定了无效的rowid
select * from class cl where cl.rowid = 'AAAMaaa';
--rownum不属于表
select st.*from student st where rownum = 1; select st.*from student st where st.rownum = 1;
--rownum不能跨过1而存在,rownum始终是从1开始顺序编号。 select * from student st where rownum < 10; select * from student st where rownum > 10; select * from student st where rownum = 1; select * from student st where rownum <> 1;
select * from student st where rownum between 2 and 30;
--先有结果集,才能有rownum select st.*,rownum from student st;
select st.*,rownum from student st order by st.sname;
select t.*, rownum from (select st.*,rownum from student st order by st.sname asc) t;
--分页查询,即查询指定范围的数据 select *
from (select st.*, rownum rn from student st where rownum < 21) t where t.rn > 9;
--查询总分数前3名的学员,显示;名次、姓名、性别、总分 --步骤一:查询前3名的总分是多少? select t.*, rownum rn
from (select distinct sum(sc.score) from student st, stscore sc
where st.studentid = sc.studentid group by st.studentid
order by sum(sc.score) desc) t where rownum < 4;
--步骤二:统计每个学员的总分 select sum(sc.score), st.studentid from student st, stscore sc
where st.studentid = sc.studentid group by st.studentid;
--步骤三:步骤一和步骤二进行关联查询
select t1.rn \"名次\姓名\性别\总分数\" from (select t.*, rownum rn
from (select distinct sum(sc.score) t_score from student st, stscore sc
where st.studentid = sc.studentid group by st.studentid
order by sum(sc.score) desc) t where rownum < 4) t1,
(select sum(sc.score) t_score, st.studentid from student st, stscore sc
where st.studentid = sc.studentid group by st.studentid) t2, student st1
where t1.t_score = t2.t_score
and st1.studentid = t2.studentid
order by t1.rn asc;
--方式二:用分析函数代替rownum
select t1.rn \"名次\姓名\性别\总分数\" from (select t.*, rank() over(order by t.t_score desc) rn from (select distinct sum(sc.score) t_score from student st, stscore sc
where st.studentid = sc.studentid group by st.studentid) t) t1, (select sum(sc.score) t_score, st.studentid from student st, stscore sc
where st.studentid = sc.studentid group by st.studentid) t2, student st1
where t1.t_score = t2.t_score
and st1.studentid = t2.studentid and t1.rn < 4 order by t1.rn;
--distinct,去除重复数据
--是所取列的值全部相同,侧视为重复数据。 --一般情况下使用group by代替distinct select st.sname from student st;
select distinct st.sname from student st;
select distinct st.sname, st.studentid from student st; select st.*
from student st,
(select max(st.studentid) studentid from student st group by st.sname) t1 where st.studentid = t1.studentid;
--oracle分析函数代替rownum
--rank() over(order by 列 asc | desc):按照列升序或降序排序之后,得到序号列。 select t.*, rownum from (select st.*,rownum from student st order by st.sname asc) t; select st.*, rownum, rank() over(order by st.sname asc) rn from student st select st.*,rank() over(order by st.sname,st.sex asc) rn from student st
因篇幅问题不能全部显示,请点此查看更多更全内容