--数据库基本表的创建,插入,删除,更新操作
--建立一个"学生"表
--学生的学号:Sno,类型是char(9)-->因为学生的学号是9位的定长的字符串;
--学生的姓名:Sname,类型是varchar2(8)-->因此可以是2,3,4汉字,而本数据库中一个汉字对应两个字符;
--学生的年龄:Sage,类型是smallint-->smallint占用的是两个字节,表示数的范围是,-32,768-->32,767;
--学生的性别:Ssex,类型是char(2)-->学生的性别只有两种情况,'男'或者'女',因此使用2位的定长字符串表示;
--学生的所属系别:Sdept,类型是varchar2(4)-->学生所属系别的长度是不确定的,假设最长4个字符;
--学生表的主键为学生的学号;
create table Student
(
Sno char(9) primary key,
Sname varchar2(8),
Ssex char(2) not null,
Sage smallint not null,
Sdept varchar2(4) not null
);
--创建学生"课程"表
--课程的课程号:Cno,类型是char-->假设课程号是4位的定长字符;
--课程的课程名:Cname,类型是varchar2-->首先课程的名字是一个字符串,假设课程名字最多有10个汉字,最多含有20个字符组成;
--课程的先行课程号:Cpno,类型是char-->这个属性的数据类型应该和课程号的数据类型是一致的;
--课程的学分:Ccredit,类型为smallint-->课程的学分是一个小正整数;
--学生"课程"表中的主键是Cno;
--学生"课程"表中的外键为Cpno;课程表中的Cpno引用自课程表中的Cno;
create table Course
(
Cno char(4) primary key,
Cname varchar2(20) not null,
Cpno char(4),
Ccredit smallint not null,
foreign key(Cpno) references Course(Cno)
);
--创建学生"选修"表
--学生的学号Sno,类型为char(9)-->学号的长度是9个数字的定长字符;
--学生的课程号Cno,类型为char(4)-->课程号的长度是4个数字的定长字符;
--学生的成绩Grade,类型为smallint-->这个整数在0->100之间的数字;
--选修表的主键:Cno和Sno的组合;
--选修表的外键:选修表中的Sno引用自学生表Student中的学号Sno;选修表中的Cno引用自学生表Courses中的课程号Cno;
create table SC
(
Sno char(9),
Cno char(4),
Grade smallint,
primary key(Sno,Cno),
foreign key(Sno) references Student(Sno),
foreign key(Cno) references Course(Cno)
);
--查询到当前数据库的字符集,
--如果value=ZHS16GBK,那么一个汉字占用2个字节,即一个汉字占用2个字符的大小;
--如果value=AL32UTF8,那么一个汉字占用3个字节,即一个汉字占用3个字符的大小;
select * from v$nls_parameters t where t.PARAMETER='NLS_CHARACTERSET';
alter user scott account unlock;
alter user sys account unlock;
alteruseruser_name account unlock identifiedby new_password;
--查询的结果显示的value = ZHS16GBK,那就说明在本数据库中一个汉字是占用两个字节的.
--向学生表中插入数据
insert into Student values('201215121','李勇','男',20,'CS');
insert into Student values('201215122','刘晨','女',19,'CS');
insert into Student values('201215123','王敏','女',18,'MA');
insert into Student values('201215125','张立','男',19,'IS');
--违背实体的完整性
insert into Student values('201215121','李白','男',20,'CS');
insert into Student values('201215122','刘备','女',19,'CS');
--违背实体的完整性
insert into Student values(null,'张三','男',19,'CS');
insert into Student values(null,'李四','男',20,'IS');
--违背用户定义的完整性
insert into Student values('201215126','张立','男',null,'IS');
insert into Student values('201215126','张立',null,30,'IS');
--查询学生的全部信息
select * from Student;
--删除学生表
drop table Student;
--向课程表中插入数据
--注意插入数据时,可能会发生违背参照的完整性-->因为Cpno字段的值可能在表中还没有被插入;
--注意插入数据式,还可能发生违背实体的完整性-->因为我们插入了一行之后,再次插入,主码和表中的重复;
insert into Course values('2','数学',null,2);
insert into Course values('6','数据处理',null,2);
insert into Course values('4','操作系统','6',3);
insert into Course values('7','PASCAl语言','6',4);
insert into Course values('5','数据结构','7',4);
insert into Course values('1','数据库','5',4);
insert into Course values('3','信息系统','1',4);
--违背了实体的完整性约束
insert into Course values('1','数据库','5',5);
insert into Course values('3','信息系统','1',4);
--违背了实体的完整性
insert into Course values(null,'数据库','5',4);
insert into Course values(null,'数据结构','7',4);
--违背了参照的完整性
insert into Course values('8','数据结构','20',4);
insert into Course values('9','数据结构','11',4);
--违背了用户自定义完整性
insert into Course values('10','数据结构','7',null);
insert into Course values('13','操作系统','6',null);
--说明在不违背子表中外码的值来自父表中主码已有的值的前提下,外码的值可以为空
insert into Course values('2','数学',null,2);
insert into Course values('6','数据处理',null,2);
--对课程表进行的查询操作
select * from Course;
--删除课程表
drop table Course;
--向选修表中插入数据
--在对选修表中的数据进行插入的时候,插入的学号和插入的课程号必须是学生表中,课程表中已经出现的值;
--选修表中的主码是学号和课程号的的组合,这时候对单一的学号或者单一的课程号来看他们是可以重复的;
--在进行数据的插入的时候组成主码的一个或者多个属性列,都不能为空
insert into SC values('201215121','1',92);
insert into SC values('201215121','2',85);
insert into SC values('201215121','3',88);
insert into SC values('201215122','2',90);
insert into SC values('201215122','3',80);
--insert into SC values('201215122','1',90);
--违反参照的完整新,子表中外码的值不能是父表中主码中不存在的值
insert into SC values('201215122','9',100);
insert into SC values('201400644','1',70);
--违背了实体的完整性,表中的主码的值必须是唯一的,不能够重复
insert into SC values('201215122','3',90);
insert into SC values('201215121','1',92);
--违背实体的完整性,组成主码的各个属性列的值不能为空
insert into SC values('201215122',null,90);
insert into SC values(null,'2',70);
--对选修表进行的查询操作
select * from SC;
--删除选修表基本表
drop table SC;
--单表查询:是指仅仅涉及一个表的查询操作
--选择表中的若干列
--单表查询语句的语法格式:
--select [all | distinct] <目标列表达式>[,<目标列表达式>,...]
--from <表名或者视图名> [[as] <别名>] [,<表名或者视图名>...](select 语句) [as] <别名>
--[where <条件表达式>]
--[group by <列名1> [having <条件表达式>]]
--[order by <列名2> [asc|desc]];
--查询全体学生的学号和姓名
--<这时候目标列表达式>---->需要查询的属性列
--该语句的执行过程:从Student表中取出一个元组,
--然后取出该元组在属性Sno和Sname上的值,
--将Sno和Sname值形成一个新的元组输出;
select Sno,Sname
from Student;
--那么显示出表的属性列的先后顺序可以和基本表中的顺序不同
--可以显示出来的属性的先后顺序是和查询SQL中指定的顺序是相同的
select Sage,Sname,Sno
from Student;
--查询出基本表中的所有的属性列有两种方式:
--查询学生表和课程表,以及选修表中的所有信息
--方式一:使用* 来代表所有的属性列
--可以将属性列的各个属性名定义成<目标表达式>可以使用"*"来代替
select *
from Student;
select *
from Course;
select *
from SC;
--方式二:将需要输出的字段的依次进行指定到select子句中
--这里的<目标表达式>---->表中各个属性列的属性名称;
--查询的结果顺序是根据目标表达式中的指定的属性列的顺序保持一致的;
select Sno,Sname,Ssex,Sage,Sdept
from Student;
select Cno,Cname,Cpno,Ccredit
from Course;
select Sno,Cno,Grade
from SC;
--查询经过计算得到的属性列的值
--select子句中的<目标表达式>---->可以是属性列的名称,也可以是一个表达式
--比如学生的出生日期"2016-Sage",年薪"12*sal"等一个表达式
--查询出全体学生的 "姓名" 以及 "出生年份";
select Sno,2016-Sage
from Student;
--我们也可以在查询表中相应属性时给属性指定一个别名
--用户可以通过指定别名的方式来改变查询结果的列标题,这个对于
--含有算术表达式,常量,函数名的目标表达式尤为有效
select Sno ,2016-Sage BirthDate
from Student;
--通常我们也可以给需要查询的属性字段指定一个中文名
--注意这个中文名字是不需要添加单引号的
select Sno 学生学号 ,2016-Sage 出生日期
from Student;
--如果添加了单引号---->提示未找到要求的from关键字
select Sno '学生学号',2016-Sage '出生日期'
from Student;
--select子句中的<目标表达式>---->字符常量:这时候该属性列的所有值都和字符常量相同
select Sno,Sname,'出生日期'
from Student;
--查询全体学生的姓名,出生日期,和所在院系,要求用小写字母表示系名
--select子句中共的<目标表达式>---->也可以是函数的形式,
select Sno,2016-Sage BirthDate,lower(Sdept)
from Student;
select Sno,2016-Sage BirthDate,upper(Sdept)
from Student;
--查询学生表中元组的个数---->基本表中的数据量,
--当需要使用select * from 基本表的时候,我们往往应该先确定下这个基本表的数据量
--如果基本表中的数据量过大,使用select * from 基本表 查询时不能很好的查看查询结果
--还可能是在数据量很大 的情况下直接使用select * from 基本表还可能出现死机的情况
--查询基本表"Student"的数据量
select count(Sno)
from Student;-->结果为4
select count(*)
from Course;-->结果为7
--说明直接在from子句中写基本表的名字,实际上是对from子句后面的表做笛卡尔积
--做笛卡尔积后得到的表的元组(记录数)=基本表1记录数*基本表2记录数*...基本表n记录数;
select count(*)
from Student,Course;-->结果为28
--由此说明count(*),count(属性列)两者的结果是等价的
--为了提高代码的可读性,应该指定一个属性列的名字
select count(Sno)
from SC;-->结果为5
select count(*)
from SC;-->结果为5
--选择表中的若干元组
--取消重复的行,两个并不完全相同的元组在投影到指定的某些列上之后查询出来的结果可能是相同的
--这样就产生了相同的行,这些相同的行有的时候,我们有时不想看到
--查询选修了课程的学生学号
select Sno
from SC;
select all Sno
from SC;
--由此说明默认情况下是使用all,将该字段的所有行进行显示,不会消除重复的行
--这时候我们发现之前在选修表中不完全相同的元组,在Sno字段的投影下,很多行出现了重复
--这是因为:一个学生可以选择多门的课程,也就产生了一个学号对应着多个课程,我们可以指定distinct来消去重复的行
select distinct Sno
from SC;