select简单查询
select查询语法
-- 查询所有
-- 结构/格式 select 查询的信息 from 数据来源
-- * 表示所有,下面语句 表示 查询一张表里的所有数据
select * from 表名;
-- 查询表中的 某个字段的数据 或者列 多个字段用英文逗号隔开
select 字段名1,字段名2 from 表名;
select去重、别名和排序
-- 去重 distinct
select distinct 字段名 from 表名;
-- 别名 给 字段/列 取别名 (俩种方法如下)
select 字段 别名,字段 别名 from 表名;
select 字段 as 别名,字段 as 别名 from 表名;
-- 排序(降序) ordey by 字段 desc
select 字段 from 表名 order by 字段(要排序的字段) desc;
-- 排序(升序) ordey by 字段 asc (asc可写可不写)
select 字段 from 表名 order by 字段(要排序的字段) asc;
-- 解析顺序 from --> select --> order by
select伪列
-- 举例:表中现有员工姓名,员工月薪两个字段 实现查出来有三列数据 姓名,月薪,年薪
select 姓名字段,月薪字段,月薪*12 from 表名;
-- 以上 月薪*12 为年薪 但是表中并没有这个字段 所以称之为伪列
-- 当然 伪列 也可以取别名
select 姓名字段,月薪字段,月薪*12 as 别名 from 表名;
select null处理
-- 举例: 表中现有 工资和提成 俩个字段,实现查询结果有三列数据 工资,提成,月薪
-- 月薪 为伪列 月薪=工资+提成 但有些员工是没有提成的(null值)
-- 对于没有提成的提成的员工来说 月薪=工资+null 这样算下来 月薪就是null了
-- 所以就要用到 nvl(exp1,res)函数处理了
-- 其中 exp1为可能为null值得字段 , res为赋值 0
select 工资字段,提成字段, 工资字段+nvl(提成字段,0) 月薪 from 表名;
-- 排序 null处理
-- nulls first 将空值放在前面
select * from 表名 order by 字段 desc nulls first;
-- nulls last 将空值放在后面
select * from 表名 order by 字段 desc nulls last;
select 拼接字符
-- 举例:现表中有 姓名 字段 要求实现查询结果为 名字+a
select 字段||'a' from 表名;
-- 字符拼接格式: 字段||'字符'
-- 可以将两个字段进行拼接 字段||字段
select 虚表
-- 虚表 dual 没有什么实际意义 一般用来计算
select 999*666 from dual;
-- 最终在窗口显示的就是 999x666的结果
以上为select简单查询 一般用来 查询所有数据或者某一些数据
select条件查询
条件查询结构
select 字段(查询内容) from 表名(数据来源) where 条件
-- 举例: 查询班里所有男同学的信息
select 字段 from 表名 where 性别='男';
-- 解析过程 from --> where(判断性别是否为男) --> select(将满足条件的数据放在结果集)
条件运算
-- =、>、<、>=、<=、<>、!=、^=、between and(判断这个值在不在区间之内 在A和B的中间 包含A和B) in(定值 满足什么条件 ) 以上 != <> ^= 都为不等于
select 字段 from 表名 where 字段=条件;
select 字段 from 表名 where 字段<条件;
select 字段 from 表名 where 字段>条件;
select 字段 from 表名 where 字段!=条件;
select 字段 from 表名 where 字段<>条件;
select 字段 from 表名 where 字段^=条件;
select 字段 from 表名 where 字段 between 条件 and 条件;
select 字段 from 表名 where 字段 in(A,B);
条件链接预算符
-- and(和 前后都要满足)、or(或者 前后满足一个)、not(不,或者取反)
select 查询内容 from 表名 where 条件A and 条件B;
select 查询内容 from 表名 where 条件A or 条件B;
select 查询内容 from 表名 where not 条件;
null运算符
-- is null(为空)、 is not null(不为空) 、 not...is null(不为空)
select 查询内容 from 表名 where 字段 is null;
select 查询内容 from 表名 where 字段 is not null;
select 查询内容 from 表名 where not 字段 is null;
模糊查询like
-- % (占位符,可以表示任意一个或者多个字符) _(占位符,可以表示一个任意的字符)
-- 举例:现表中有 刘德华、刘淑芳、郭德纲 、马德华 四个同学 要求查询 所有姓刘的同学
select * from 表名 where 字段 like '刘%';
-- 举例:现表中有 刘德华、郭德纲、缺德、马德华 四个同学 要求查询 所有名字带德的同学
select * from 表名 where 字段 like '%德%';
-- 举例:现表中有 刘德华、郭德纲、缺德、马德华 四个同学 要求查询 所有名字最后一个字为华的同学
select * from 表名 where 字段 like '%华';
-- 举例:现表中有 刘德华、郭德纲、缺德、马德华、欧阳德华 四个同学 要求查询 所有名字第二个字为华的同学
select * from 表名 where 字段 like '_华%';
-- 举例:现表中有 刘德华、郭德纲、缺德、马德华、欧阳德华 四个同学 要求查询 所有名字倒数第二个字为德的同学
select * from 表名 where 字段 like '%德_';
where条件子句查询
-- 假如涉及到两张表或多张表
-- 现有 学生表(学号,姓名) 和 班级表(学号,班级) 实现结果集 姓名+班级
-- 假如要查询 3班的学生信息
select 姓名 from 学生表 where 班级=(select 班级 from 班级表 where 班级=3)
-- 子查询 between and 写法
select 数据内容 from 数据来源 where 字段
between
(select 数据内容 from 数据来源 where 条件)
and
(select 数据内容 from 数据来源 where 条件)
函数
内置函数
单行函数
-- 单行函数:对应在表记录中,一条返回一个结果
字符函数
-- 常用的单行函数
-- concat(x.y) 链接字符串x和y
select concat(字段x,字段y) as 别名 from 表名;
-- instr(x,str,start,n)在x中查找str,可以指定从start开始,也可以指定从第n次开始
-- 假设有一个字符串'helloword' 请找出'e'
select instr('hellowork','e')from dual;
-- 假设有一个字符串'helloword' 请找出'l'
select instr('hellowork','l')from dual;
-- 假设有一个字符串'helloword' 请找出第二个'l'
select instr('hellowork','l',1,2)from dual;
select instr('hellowork','l',从什么位置找,找第几次出现的)from dual;
-- 假设找出 表中某列 并包含'A'
select instr(字段,'A')from 表名;
-- length(x)返回x的长度
-- 显示'hello'的字符长度
select length('hello') from dual;
-- 查看表中某列的所有数据的各个字符串长度
select lenght(字段) from 表名;
-- 将查询的内容按照字符串长度进行排序
select lenght(字段) from 表名 order by lenght(字段);
-- lower(x)将x转换为小写
select lower(字段) from 表名;
-- upper(x)将x转换为大写
select upper(字段) from 表名;
-- ltrim(x,trim_str)把x左边截去trim_str字符串,缺省截去空格
-- 现有字符串' abc abc ' 要去除字符串左边的空格
select ltrim(' abc abc ')from dual;
-- 'aaa123bbb' 去除左边的aaa
select ltrim('aaa123bb','aaa')from dual;
-- rtrim(x,trim_str)把x右边截去trim_str字符串,缺省截去空格
-- 现有字符串' abc abc ' 要去除字符串右边的空格
select rtrim(' abc abc ')from dual;
-- 'aaa123bbb' 去除右边的bbb
select rtrim('aaa123bb','bbb')from dual;
-- replace(x,old,new)在x中查找old,并替换为new
-- 'abc123' 将a换成b
select replace('abc123','a','b') from dual;
-- substr(x(字段),start(开始),length(长度))返回x的字符串,从start开始,截取length个字符,缺省length,默认到结尾
-- 'abc' 截取 bc
select substr('abc',2)from dual;
-- 'abc' 截取 b
select substr('abc',2,1)from dual;
日期函数
-- sysdate 当前系统时间
select sysdate from dual;
-- 获取后一天的时间
select sysdate+1 from dual;
-- current_date 返回当前的系统日期
select current_date from dual;
-- add_months(d1,n1) 返回在日期d1基础上再加上n1个月后新的日期
select add_months(字段,3(1~12)) from dual;
-- last_day(d1) 返回日期d1所在月份最后一天的日期
-- 查看本地时间的月份最后一天
select last_day(sysdate) from dual;
-- 查看表中某个字段的 最后一天
select last_day(字段) from 表名;
-- months_between(d1,d2) 返回日期d1到日期d2之间的月数
select 开始时间,结束时间,months_between(结束时间,开始时间) from 表名;
-- next_day(d1,[c1]) 返回日期d1在下周,星期几(参数c1)的日期
-- 举例:获取当前时间点的下一个星期一是什么时候
select next_day(sysdate,'星期一') from dual;
select 字段,next_day(字段,'星期一') from 表名;
转换函数
-- to_char(x,c) 将日期或数据x按照c的格式转换为char数据类型
-- yyyy代表年 mm代表月 dd代表天
select to_char(字段,'mm/dd/yyyy') from 表名;
select to_char(字段,'mm"月"dd"日"yyyy"年"') from 表名;
-- to_date(x,c) 将字符串x按照c的格式转换为日期
-- 假如现有字符串 '1990/01/01'
select to_date('1990/01/01','yyyy/mm/dd') from dual;
-- 如果to_date('1990/01/01','yyyy/mm/dd')+4 其结果就是 1990/1/5
-- to_number(x) 将字符串x转化为数字型
-- 一般用于 十六进制的转换 这里作为了解就可以
select to_number('11','xx') from dual;
-- 其结果集显示的17
多行函数
-- 多行函数:也称'组函数'或'聚合函数'(重点):此类函数可同时对多条记录进行操作,并返回一个结果
-- 常用的组函数
-- avg() 平均值
select avg(字段) from 表名;
-- sum() 求和
select sum(字段) from 表名;
-- min() 最小值
select min(字段) from 表名:
-- max() 最大值
select max(字段) from 表名;
-- count() 统计
select count(字段) from 表名;
-- 注意:null不参与运算 也就是说 表中某个字段 有5条数据 但是其中有两条为null 则查询出来为3
-- 去重统计
select count(distinct 字段) from 表名;
group by分组
-- 结构
select 字段 from 表名 group by 字段;
having过滤组信息
-- 结构
select 字段 from 表名 having 条件;
过滤行记录和组信息
-- 行记录的过滤是针对每条记录的筛选,组信息是针对组的筛选,是可以同时出现的,先筛选行,再过滤组,
where 筛选行,只出现行信息
having 过滤组,只能出现组信息
-- 结构
select ... from ... where ... group by ... having...
-- from --> whrer --> group by -->having --> select
分页和去重
分页介绍
真假分页
-- 假分页
假设有100条数据,第一页就是第1条数据到第10条数据,第二页就是从第11条数据到第20条数据,是一下全部查出来的,也只用一条sql语句
好处:和数据库交互少
坏处:浪费内容
-- 真分页
发送sql语句,第一页显示10条数据。但我查询第二页的时候,我需要再次发送sql语句,去查出第11到20的数据。
好处:内存少,精确
坏处:需要与数据库频繁交互
rownum分页
-- rownum不是一个真是存在的列,它是用于从查询返回的行的编号,返回的第一行分配的是1,第二是2,以此类推,这个伪字段可以用于限制查询返回的总行数。
-- 写法结构
select 字段,rownum from 表名;
-- 实现分页
-- 假设表中有十条数据 我要进行分页 每一页显示五条数据
select 字段 from 表名 where rownum<=5;
-- 当我要显示第二页的时候(6~10)
select 字段,rownum from (select 字段,rownum 别名 from 表名) where 别名>5 and 别名<=10;
rownum分页去除重复记录
-- rowid 介绍
-- 并不是真是存在的 属于伪列 根据每一行数据的物理地址信息编码而成的一个伪列,所以根据一行数据的rowid就能找到一行数据的物理地址信息。从而快速的地位到数据行。 数据库的大多操作都是通过rowid来完成的,而且使用rowid来进行记录定位速度是最快的。
-- 准备数据(备份)
create table 备份表名 as select * from 表名;
-- rowid 结构
select 字段,rowid from 表名;
-- 假设 表中有重复的行数据 将所有相同的记录只保留一份
-- 实现步骤
-- 将数据进行分组 按照重复信息进行分组
-- 在每一组中 选取一条记录进行保存,找到特性
-- 删除时,找哪些不在保留范围内的数据。
delete from 表名 where rowid not in(
select min(rowid) from 表名 group by 字段,字段,字段;
);
commit; -- 也可以按F10 进行提交
表连接
介绍
-- 比方说我需要从一张班级表找出山西地区的学生,在根据这个信息去成绩表里面查询他们的成绩,如果没有夺标链接,那么我们就只能手动将从第一张表中查询出来的信息,作为第二张表的检索信息去查询最后的结果。这样回显得很麻烦,过程过去繁琐
-- 链接查询
-- 1)在查询的时候同时需要多张表(特别时存在外键关系的),此时需要多张表之间的值进行链接。
-- 2)目前sql标准提出过俩种链接查询,第一种是较早的SQL92标准,第二种是目前使用广泛的较新的SQL99标准
-- 3)92形式简单,但编写较为冗(rong)长,而99不仅在底层得到优化,而且形式看上去更加一目了然,逻辑性更强,一般建议使用99标准
92语法
-- SQL92标准 写法/结构
-- 多张表需要全部放在from之后,所有的连接条件都放在where当中。说白了 它的等值连接、非等值连接、外连接等等其实只是where条件的筛选
-- 结构 select。。from.. 表1,表2,表3。。where..
-- 笛卡尔积
-- 通俗来讲,就是两个集合里面的每一个成员,都与对方集合中的任意一个成员有关联
-- 举例:假如有个考勤表,记录着100个人每月的打卡信息,理论上每个人每天都有打卡记录,但有忘记打卡,请假,旷工的。对应的就缺少了。那我们在查询的时候 不管是一天一天查还是一个人一个人的查,都会有些麻烦。在这种情况下我们就要针对每个人与每一天做一个笛卡尔积的处理,然后与实际的表去进行关联。就很容易查询出结果了。
select * from 表1,表2 order by 字段;
等值连接
-- 在笛卡尔积的基础上取条件列相同的值 比如查询员信息和部门信息 我们要查询出部门信息,然后根据这个部门信息查询这个部门里面的所有员工信息
-- 写法
select * from 表1 别名1,表2 别名2 where 别名1.字段 = 别名2.字段;
非等值连接
-- !=、>、<、<>、between and
-- 举例: 现有两张表 学生表(学号、姓名、成绩) 成绩表(学号、等级、最低成绩、最高成绩)
-- 要求查询 每个学生的学生等级
select 学号,姓名,成绩,成绩等级 from 学生表 别名1,成绩表 别名2 where 别名1.成绩 between 最低工资 and 最高工资;
自连接
-- 特殊的等值连接(来自于同一张表)
-- 举例: 现有一张员工表(员工编号、员工姓名、上级编号、上级信息)员工A的上级领导是上级B 但是上级B也是有上级领导C的
-- 实现查询出结果集 格式如下:
-- 员工A编号-员工A姓名-上级B编号--上级B姓名--上级C编号--上级C姓名
select * from 员工表 别名1,员工表 别名2 where 别名1.上级编号 = 别名2.员工编号
外连接
-- 介绍:外连接可以分为左外连接(左边的表是主表)和右外连接(右边的表是主表)或者完整外部连接(可以是两张表为主表)
-- 举例:现有两张表 班级表(班级号、班级名称) 和 学生表(学生姓名和班级号)但是 班级表里有1234四个班级号 但学生表的学生都在123三个班里 也就是说4班是没有人的 现在我要统计每个班级里的学生数
-- 以上情况是内连接来做的话 其结果集只会显示123三个班的人数,而4班是不显示的 所以这个时候我们就要用到外连接了
select * from 班级表 别名1,(select count(*),班级号 from 学生表 group by 班级号) 别名2 where 别名1.班级号 = 别名2.班级号(+)
-- 以上查询出来的4班值为空
select 别名1.班级号,班级名称,nvl(别名3,0) from 班级表 别名1,(select count(*) 别名3,班级号 from 学生表 group by 班级号) 别名2 where 别名1.班级号 = 别名2.班级号(+);
-- 以上查询的结果集4班为0 利用nvl进行null处理
-- 以上带“+”的是附属表,不带“+”的是主表
99语法
-- 99与92的区别:多个字段不在用逗号隔开,而是使用关键字连接
cross join
-- 交叉连接,实现笛卡尔积
select * from 表1 cross join 表2;
natural join
-- 需要有(同名列、主外键) 必须有同名列
-- 自然连接,做等值连接
-- 查询所有员工姓名及所在部门的名称
-- 举例:现有两张表,学生表(学生姓名,班级编号),班级表(班级编号,班级名称)
-- 要求查询:学生姓名、班级编号以及学生所在的班级名称
select 学生姓名,班级编号,班级名称 from 学生表 natural join 班级表;
join using
-- 要求:两张表中必须有同样的列
-- using 连接,等值连接
-- 举例:现有两张表,学生表(学生姓名,班级编号),班级表(班级编号,班级名称)
-- 要求查询:学生姓名、班级编号以及学生所在的班级名称
select 学生姓名,班级编号,班级名称 from 学生表 join 班级表 using(班级编号);
join on
-- on连接,可做等值连接、非等值连接、自连接,可以解决一切连接,关系列必须要区分
-- 举例:现有两张表,学生表(学生姓名,班级编号),班级表(班级编号,班级名称)
-- 要求查询:学生姓名、班级编号以及学生所在的班级名称
select 学生姓名,班级编号,班级名称 from 学生表 join 班级表 on 学生表.班级编号 = 班级表.班级编号;
outer join
-- 外连接,有主表和从表
-- left[outer]join on 左外连接
-- 举例: 现有一张员工表(员工编号、员工姓名、上级编号、上级信息)员工A的上级领导是上级B 但是上级B也是有上级领导C的
-- 实现查询出结果集 格式如下:
-- 员工A编号-员工A姓名-上级B编号--上级B姓名--上级C编号--上级C姓名
select 别名1.员工编号,别名1.员工姓名,别名1.上级编号,别名2.上级信息
from 员工表 别名1 left outer join 员工表 别名2 on 别名1.上级编号 = 别名2.员工编号;
-- left[outer]join using
-- right[outer]join on 右外连接
-- 举例: 现有一张员工表(员工编号、员工姓名、上级编号、上级信息)员工A的上级领导是上级B 但是上级B也是有上级领导C的
-- 实现查询出结果集 格式如下:
-- 员工A编号-员工A姓名-上级B编号--上级B姓名--上级C编号--上级C姓名
select 别名1.员工编号,别名1.员工姓名,别名1.上级编号,别名2.上级信息
from 员工表 别名2 right outer join 员工表 别名1 on 别名1.上级编号 = 别名2.员工编号;
-- right[outer]join using
full join on | using
-- 全连接,满足则直接匹配,不满足的相互补充null,确保所有的表记录都至少出现一次。
92与99的区别
-- 92标准
-- 内连接
select ... from 表1,表2 where 表1.字段 = 表2.字段;
-- 外连接
select ... from 表1,表2 where 表1.字段 = 表2.字段(+);
-- 99标准
-- 内连接(笛卡尔积、等值连接、非等值连接、自连接)
select ... from 表1 cross join 表2 where ...;
select ... from 表1 natural join 表2 where ...;
select ... from 表1 join 表2 using(同名字段) where ...;
select ... from 表1 join 表2 on 连接条件 where ...;
-- 外连接
select ... from 表1 right outer join 表2 on 连接条件 where ...;
-- 全连接
select ... from 表1 join 表2 on 连接条件 where ...;
集合操作
-- 通过一些关键字将我们的结果集进行一个拼接操作
-- 什么时候能做集合操作?但俩个结果集 字段个数和字段类型一一对应的时候才能做集合操作
-- union 并集(去重)对两个结果集进行并集操作,不包括重复行同时进行默认规则的排序;
select 'a','b' from dual union select 'c','d' from dual;
-- union all 全集(不去重)对两个结果集进行并集操作,包括重复行,不进行排序
select 'a','b' from dual union select 'c','d' from dual union all select 'a','b' from dual;
-- intersect 交集(找出重复)对俩个结果集进行交集操作,不包括重复行,同时进行默认规则的排序
(select 'a','b' from dual union select 'c','d' from dual)
intersect
(select 'a','b' from dual union select 'e','f' from dual)
-- Minus 差集(减去重复)对俩个结果集进行差操作,不包括重复行,同时进行默认规则的排序
(select 'a','b' from dual union select 'e','f' from dual)
minus
(select 'a','b' from dual union select 'c','d' from dual)
DDL介绍
-- DDL语句:数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象。常用的语句关键字主要包括create、drop、alter等。
-- DML语句:数据操作语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性。常用的语句关键字主要包括:insert、dalete、update和select等。
-- DCL语句:数据控制语句,用于控制不同数据段直接的许可和访问级别的语句,这些语句定义了数据库、表、字段、用户的访问权限和安全级别,主要的语句关键字包括grant、revoke等。
表操作
创建表
-- 创建新表
create table 表名(
字段名 类型(长度),
...其他字段...
);
-- 数据类型
VARCHAR2(size) 可变长度的字符串,最大长度为size个字节;size的最大值为4000,最小值为1.必须指定
NVARCHAR2(size) 可变长度的字符串,最大长度为size个字节;size的最大值为4000,必须指定
NUMBER(p,s)
LONG 可变长度的字符串,长度可大2G个字节
DATE 有效日期范围从公元强4712年1月1日到公园后4712年12月31日
RAW(size)长度为size字节的原始二进制数据,size最大值为2000字节,必须指定
LONG RAW 可变长度的原始二进制数据,长度可大2G个字节
CHAR(size)固定长度的字符数据,其长度为size个字节,size最大为2000个字节,而最小值和默认值是1
NCHAR(size)固定长度,根据Unicode标准定义
CLOB 一个字符大型对象,可容纳单字节的字符,不支持宽度不等的字符集,最大为4G
NCLOB 一个字符大型对象,可容纳单字节的字符,不支持宽度不等的字符集,最大为4G
BLOB 一个二进制大型对象,最大4G字节
BFILE 包含一个大型二进制文件的定位器,其存储在数据库的外面;使得可以以字符流I/O访问存在数据库服务器上的外部LOB;最大4G字节。
-- 从其他表拷贝结构
create table 表名 as select 字段列表 from 已有表 where 1!=1;
修改表结构
-- 修改表名
rename 原表名 to 新表名
-- 修改列名
alter table 表名 rename column 列名 to 新列名
-- 修改字段类型
alter table 表名 modify(字段 类型)
-- 添加列
alter 他变了 表名 add 字段 类型
-- 删除列
alter table 表名 drop column 字段
删除表
drop table 表名;
约束
-- 五种约束 (约束就是对数据更加精确的控制,更加符合实际,满足我们的需求)
主键约束(PRIMARY KRY)
唯一性约束(UNIQUE)
非空约束(NOT NULL)
外键约束(FOREIGN KEY)
检查约束(CHECK)
主键约束(PRIMARY KRY)
主键是定位表中单个行的方式,可唯一确定表中的某一行,关系型数据库要求所有表都应该有主键,不过Orcale没有遵守此范例要求,Orcale种的表可以没有主键(这种情况很少)
1.键列必须具有唯一性,且不能为空。主键约束就相当于 UNIQUE+NOT NULL
2.一张表只能有一个主键
3.主键所在列必须具有索引(主键的唯一约束通过索引来实现),如果不存在,将会在索引添加的时候自动创建
唯一性约束(UNIQUE)
唯一性约束可作用在单列或多列上,对于这些列或列组合,唯一性约束保证每一行的唯一性。
UNIQUE需要注意:
1.对于 UNIQUE约束来讲,索引是必须的。如果不存在,就自动创建一个( UNIQUE的唯一性本质上是通过索引来保证的)
2.UNIQUE允许null值, UNIQUE约束的列可存在多个null。这是因为, unique 唯一性通过 btree索引来实现,而 btree索引中不包含null。当然,这也造成了在 where 语句中用null值进行过滤会造成全表扫描。
非空约束(NOT NULL)
非空约束作用的列也叫强制列。顾名思义,强制键列中必须有值,当然键表时候若使用 default 关键字指定了默认值,则不能输入
外键约束(FOREIGN KEY)
外键约束定义在具有父子关系的子表中,外键约束使得子表中得列对应父表的主键列,用以维护数据库的完整性。不过出于性能和后期的业务系统的扩展的考虑,很多时候,外键约束仅出现在数据库的设计中,实际会放在业务程序中进行处理。
外键约束需注意一下几点:
1.外键约束的子表中的列和对应父表中的列数据类型必须相同,列名可以不同。
2.对应的附表列必须存在主键约束或唯一约束
3.外键约束列允许 NULL值,对应的行就称了孤行。
检查约束(CHECK)
检查约束可用来实施一些简单的规则,比如列值必须在某个范围内。检查的规则必须是一个结果为 true或 false的表达式
根据要求创建表及约束
表名:tb_user(用户表)
编号 | 字段名 | 字段类型 | 说明 |
---|---|---|---|
1 | userid | number(5) | 用户id,主键 |
2 | username | varchar2(30) | 用户名,非空,4~20个字符 |
3 | userpwd | varchar2(20) | 密码,非空,4~18个字符 |
4 | age | number(3) | 年龄,默认18,值大于等于18 |
5 | gender | char(2) | 性别,默认‘男‘,只能是男和女 |
6 | varchar2(30) | 邮箱,唯一 | |
7 | regtime | date | 注册日期,默认当前日期 |
注意:根据系统的编码去更改字符长度 比如,utf-8编码中
create table td_user(
userid number(5) primary key,
username varchar2(30) check(length(username) between 4 and 20) not null,
userpwd varchar2(20) not null check(length(userpwd) between 4 and 18),
age number(3) default(18) check(age>=18),
gender char(2) default('男') check(gendar in('男','女')),
email varchar2(30) unique,
regtime date default(sysdate)
);
表名:tb_txt(文章表)
编号 | 字段名 | 字段类型 | 说明 |
---|---|---|---|
1 | txtid | number(5) | 文章编号,主键 |
2 | title | varchar2(32) | 文章标题,非空,长度为4~20字符 |
3 | txt | varchar2(1024) | 内容,最大长度为1024 |
4 | pubtime | date | 发布日期,默认当前日期 |
5 | userid | number(5) | 作者,外键,参考用户表的用户id,删除时,自设为null |
create table tb_txt(
txtid number(5) primary key,
title varchar2(32) not null check(length(title)>=4 and length(title)<=30),
txt varchar2(1024),
pubtime date default(sysdate),
userid number(5) references tb_user(userid) on delete set null
);
-- 还有一种方法创建约束 (了解)
create table tb_txt(
txtid number(5),
title varchar2(32),
txt varchar2(1024),
pubtime date default(sysdate),
userid number(5),
constraint pk_txt_id primary key,
constraint ck_txt_title check (length(title)>=4 and length(title)<=30),
constraint fk_txt_user_id foreign key(userid) references tb_user(userid) on delete set null
);
追加约束
-- 追加主键约束
alter table 表名 add constraint 约束名字 primary key (要加约束的字段);
-- 追加检查约束
alter table 表名 add constraint 约束名字 check(
length(要加约束的字段) between 4 and 20
)
-- 追加非空约束
alter table 表名 modify(要加约束的字段 constraint 约束名字 not null);
-- 追加唯一约束
alter table 表名 add constraint 约束名字 unique(加约束的字段);
-- 追加默认约束
alter table 表名 modify(字段 default(值));
-- 追加外键约束 (强制不让删)
alter table 表名 add constraint 约束名字 foreign key(加约束的字段)references 表名2(字段)
-- 追加外键约束 (自动设为null)
alter table 表名 add constraint 约束名字 foreign key(加约束的字段)references 表名2(字段)on delete set null;
-- 追加外键约束 (级联删除)
alter table 表名 add constraint 约束名字 foreign key(加约束的字段)references 表名2(字段)on delete cascade;
修改约束
-- 修改约束 其实就去 先删除后修改
-- 先删除:
alter table 表名 drop constraint 约束名字;
-- 然后再添加约束(参考上方追加约束)
约束的启用和禁用
-- 启动/禁用(enable/disable)是否对新变更的数据启用约束验证
-- 验证/非验证(validate/novalidate)是否对表中已客观存在的数据进行约束验证
enable validate -- 默认的约束组合状态,无法添加违反约束的数据行,数据表中也不能存在违反约束的数据行
enable novalidate -- 无法添加违反约束的数据行,但对已存在的违反约束的数据行不做验证
disable validate -- 可以添加违反约束的数据行,但对已存在的违法约束的数据行会做约束验证
disable novalidate -- 可以添加违法约束的数据行,对已存在的违法约束的数据行也不做验证
删除约束
alter table 表名 drop constraint 约束名 ;
DML
DML介绍
-- DML数据操控语言,用于操作数据库对象中包含的数据,也就是说操作的单位是记录
-- Oracle数据库的DML表数据的操作有三种:
insert -- 插入:向数据库表插入一条记录
update -- 更新:删除数据表中的一条或多行的记录
delete -- 删除:用于修改已存在表中的记录的内容
DML之insert
-- 结构
-- 默认插入:数据必须和表结构里面字段顺序以及个数保持一致;当某个字段存在默认值时,也必须给出值。
insert into 表名 values(1,'值1','值2',null,sysdate);
commit; -- commit 提交事务 如果不些commit的话 那么这条数据不会立马插入到我们的表中,只是放在缓存中。
-- 如果不用默认时间就用 to_date('1990-1-1','yyyy-mm-dd')
-- 在创建表的同时,添加记录
-- 举例:现有一张表,里面存放了字段1,字段2,字段3,字段4.现在我要创建一张新表,发现新表需要存储的记录,在老表中有。
create table 新表明 as select 字段1,字段2,字段3 from 老表名;
-- 从其他数据表中拷贝数据进来(假设我要在我的新表里面插入数据,发现这些数据在老表中就有存储)
insert into 新表 value(select 字段 from 老表 where 条件);-- 没有条件可以省略 或者1=1
-- 在添加时指定列和顺序
-- 假设 我表中有 五个字段 字段1,字段2,字段3,字段4,字段5;但是我现在只想给 字段1,字段3,字段5中添加数据
insert into 表名(字段1,字段3,字段5)values('值','值','值');
-- 以上的字段的顺序可以随意颠倒,但values中的值就要跟着前面的字段顺序去写入
-- 如果某些字段,值可以为null或者有默认值,此时我们可以不指定。(例如:上方中我的字段2和字段4就有默认值或者可以为null)
-- 如果某个字段有默认值,则未指定时使用默认值填充
-- 如果某个字段没有默认作,但可以为null,未指定时,则使用null填充
-- 如果某个字段既可以为null,又有默认值,若未指定,则使用默认值填充,想要设为null,必须手动指定。
-- 同过指定列的方式,同其他表中查询数据,添加到表中
insert into 表名1(字段1,字段2,字段3)(select 字段1,字段2,字段3 from 表名2 where 条件)
-- 此时就不需要哪个字段跟哪个字段对应了,只要字段的数据类型兼容就可以插入
-- 在添加的记录中,存在外键关联时需要注意,可以采取想查询后添加的方式。如下:
insert into 表名1(字段1,字段2,字段3)values(01,'刘德华',(select 字段3 from 表名2 where 条件));
DML之update
-- 通过update语句可以更新(修改)表中的记录值。
update 表名 set 字段1=值1 where 条件;
-- 以上就是update的语法结构,当需要更新多个字段值时需用逗号隔开。
-- 也可以先列出需要修改的字段,通过查询子句设定。如下:
update 表名1 set(字段1,字段2)=(select '值1','值2' from dual) where 条件;
DML之delete
-- 通过delete语句可以删除表中的记录;语法结构如下:
delete from 表名1 where 条件;
-- 当两张表存在主外键关系时,如果删除主表(被参考的表)中被引用(被参考)的记录时会出现以下三种情况:(参考上面的追加外键约束)
-- 如果默认外键处理方式,强制不让删
-- 如果是 on delete cascade 一起删除
-- 如果是 on delete set null 自动设为null
更多推荐
Oracle SQL学习笔记或教程,教科书版级别的笔记。看完你就会了!!
发布评论