Oracle中SQL操作与查询

1. SQL简介

    Oracle中SQL由如下命令组成:

  • DDL(数据定义语言)
        CREATE(创建)命令、ALTER(修改)命令、DROP(删除)命令等。
  • DML(数据操作语言)
        INSERT(插入)命令、UPDATE(更新)命令、DELETE(删除)命令、SELECT … FOR UPDATE(查询)命令等。
  • DQL(数据查询语言)
        基于查询语句、Order By子句、Group By子句等。
  • TCL(事务控制语言)
    COMMIT(提交)命令、SAVEPOINT(保存点)命令、ROLLBACK(回滚)命令。
  • DCL(数据控制语言)
        GRANT(授权)命令、REVOKE(撤销)命令。

2. Oracle中的数据类型

Oracle中常见的数据类型有:

类型含义
char(length)存储固定长度的字符串。参数length指定了长度,如果存储的字符串长度小于length,用空格填充。默认长度是1,最长不超过2000字节。
varchar2(length)存储可变长度的字符串。length指定了该字符串的最大长度。默认长度是1,最长不超过4000字符。
number(p, s)既可以存储浮点数,也可以存储整数,p表示数字的最大位数(如果是小数包括整数部分和小数部分和小数点,p默认是38为),s是指小数位数。
date存储日期和时间,存储纪元、4位年、月、日、时、分、秒,存储时间从公元前4712年1月1日到公元后4712年12月31日。
timestamp不但存储日期的年月日,时分秒,以及秒后6位,同时包含时区。
clob存储大的文本,比如存储非结构化的XML文档
blob存储二进制对象,如图形、视频、声音等。

其中,对于number类型:

格式输入的数字实际的存储
NUMBER1234.5671234.567
NUMBER(6,2)123.4567123.46
NUMBER(4,2)12345.67输入的数字超过了所指定的精度,数据库不能存储

对于日期类型,可以使用sysdate内置函数获取当前系统的系统日期和时间,返回的是date类型,使用systimestamp函数可以返回当前日期、时间和时区。

select sysdate,systimestamp from dual;

Oracle中必须使用 select 列... from 表 的完整语法,当查询单行函数时,from后面使用 dual 表,dual表在系统重只有一行一列,该表在输出单行函数时是为了 select 列... from 表 的完整语法而使用的。

3. 创建表和约束

3.1 表结构

创建表语法:

CREATE TABLE 表名(
	字段名称 类型  约束,
	字段名称 类型  约束,
	字段名称 类型  约束
);

Oracle中不区分大小写,并且Oracle中创建表时不能直接添加字段注释,添加字段注释需要单独执行 comment 命令:

-- 给表添加注释
comment on table 表名 is '表名注释';
-- 给字段添加注释
comment on column 字段名 is '字段名注释';

Oracle中更新表结构:

-- 添加字段
alter table 表名 add 字段 类型 约束;
-- 修改字段类型
alter table 表名 modify 字段 类型 约束;
-- 修改字段名称
alter table 表名 rename column 原来的字段名 to 新的字段名;
-- 删除字段
alter table 表名 drop column 字段名; 

3.2 约束

Oracle中约束有如下:

  • not null 非空约束,字段不允许为空。
  • default 默认值约束,如果该列为null就使用默认值填充。
  • unique 唯一性约束,有数据的情况下,该列不能出现重复记录,null 不包括在内。
  • primary key 主键约束,能够唯一标识字段的约束,主键修饰的字段是不能重复且不能出现空值的。
  • foreign key 外键约束,表与表之间的关联关系。
  • check 检查约束,在字段类型的基础上,更进一步的提升数据的精度。例如:
DROP TABLE t_student;
CREATE TABLE t_student(
	id  number(5) unique not null , -- 学生编号
	name varchar2(20)  not null, -- 学生的姓名
	--age number(2)  check(age > 1 and age < 25), -- 学生的年龄
	age number(2)  check(age between 1 and 25), -- 学生的年龄
	address varchar2(100),  -- 学生的地址
	gender char(3) check (gender in ('男','女'))
);

4. DML语句

4.1 INSERT

INSERT INTO 表名(fieldName1,fieldName1,...fieldNameN)values(value1,value2,...,valueN)
-- 案例
insert into t_class(id,name)values(1,'计算机1班');

4.2 DELETE

 DELETE FROM 表名 [where 条件]
 delete from t_class where id = 17;
 -- 对于null的查询我们是用 is null 来匹配的
 delete from t_class where name is null;
 
 -- delete 删除会做数据的缓存,能回滚,会删除表中的所有的数据,效率低
delete from t_class ; 
-- 删除全表的数据,直接删除数据,不做缓存处理,不能回滚, 效率高,风险大
truncate table t_class ;

4.3 UPDATE

UPDATE 表名 SET field1=value1,field2=value2 ... [where 条件]
update t_class set name = '软件班级' ;

4.4 多行插入

-- 多行插入
insert into t_class_copy(id,name) select id,name from t_class;
--复制表,不带数据
create table t_class_copy as select * from t_class where 1!=1;
-- 复制表,带数据
create table t_class_copy as select * from t_class;

4.5. 序列号

应用场景:主键,插入时要保证其唯一性

  • Oracle中提供了序列化
  • MySQL中则是采用主键自增
  • 分布式环境则是采用分布式ID

创建序列号语法:

create sequence 序列名称
[increment by] -- 每次自增的数量
[start with 1] -- 从1开始计数
[nomaxvalue] -- 不设置最大值
[nocycle] -- 一直累加,不循环
[cache 10]; -- 缓存10

序列号使用:

-- 从1开始,每次+1
create sequence s_student;
-- 获取+1后的值
select s_student.nextval from dual;
-- 获取当前序列值,currval只有在执行了nextval后才会生效
select s_student.currval from dual;
-- 插入到表中
insert into t_student values(s_student.nextval, '软件2班');

5. DQL语句

基本语法:

--语法结构
SELECT <列名>
FROM <表名>
[WHERE <查询条件> ]
[ORDER BY <排序的列名>[ASC或者DESC] ]
[GROUP BY <分组字段> ]

5.1 简单查询语句

-- 1. 查询所有列
select * from t_student;
-- 2. 查询特定列
select id,name,age from t_student;
-- 3. 查询字段使用别名
-- 3.1 查询字段别名只能用双引号"而不能使用单引号'
-- 3.2 别名的双引号"可以省略
-- 3.3 当别名包含特殊字符,必须添加双引号"
select
	id as "学生编号",
	name as 学生姓名,
	age as "【学生年龄】"
from t_student;
-- 4. 查询字段中添加常量
select id,name,age,55 as 体重 from t_student;
-- 5. 拼接内容,oracle中拼接使用的是 ||
select id,name,age,'【' || id || '-' || 'name' || '】' as 组合名 from t_student;

5.2 聚合函数

聚合函数常用于统计。

-- 1. 统计学生人数,count(字段名)统计该列数据不为空的记录数
select count(*),count(name),count(gender),count(age),count(1) from t_student;
-- count(*) 会统计所有列,选出值最大的,效率低;
-- count(1) 则是给没列添加了一列为1的常量,等同于:
-- select t_student.*,1 from t_student;
-- 2. 其它统计函数
select count(1),max(age),min(age),sum(age),round(avg(age)) from t_student ;

5.3 分组函数

分组函数 group by

-- 1. 不与聚合函数一起使用时,作用与 `distinct` 是一样的,可以去重
select deptno from emp group by deptno;
-- 等同于
select distinct deptno from emp;
-- 2. 与聚合函数一起使用,聚合函数统计的就不是查询的所有数据了,而是分组后的数据
-- 分组后的数据中不能出现非分组的字段
-- 2.1 统计出学生表中男生和女生的人数
select gender,count(1) from t_student group by gender;
-- 2.2 统计出学生表中每个班级的人数
select class_id,count(1)  from t_student t group by t.class_id;
-- 2.3 统计出学生表中每个班级中的男生和女生人数 聚合函数统计的是分组后的最小单位的数据
select class_id,gender,count(1) from t_student group by class_id ,gender ;
-- 2.4 统计出学生表中年龄大于18的男生和女生的人数
select gender,count(1)
from t_student
where age > 18 -- where 的位置,必须是要在group by 之前。作用呢是筛选要分组的数据
group by gender
-- 2.5 统计出学习表中年龄大于18的班级人数大于1的记录
select class_id,count(1)
from t_student
where age > 18
group by class_id
having count(1) > 1 -- 在group by 之后。和group by 配合使用。作用是过滤分组后的数据

5.4 多表查询

-- 1. 交叉连接,获取两张表的笛卡尔积
select * from t_class cross join t_student ;
select t1.*,t2.* from t_student t1,t_class t2;
-- 2. 等值连接
select t1.*,t2.* 
from t_student t1,t_class t2 -- 1000 * 1000 = 100w
where s.class_id = c.id; -- where是在结果集加载到内存后才会做筛选
-- 3. 内连接,左表中记录和有表中记录连接时就会根据on中的条件进行过滤,满足才获取,否则直接丢失
select t1.*,t2.*
from t_student t1 
	inner join t_class t2 on t1.class_id = t2.id;
-- 4. 左连接,在内连接的基础上,让左表每条记录一一去匹配右表所有记录,右表不匹配的字段均为NULL
select t1.*,t2.*
from t_student t1 left outer join t_class t2
on t1.class_id = t2.id;
-- 5. 右连接,在内连接基础上,让右表每条记录一一去匹配左表所有记录,左表不匹配的字段均为NULL
select t2.*,t1.*
from t_student t1 
	right outer join t_class t2 on t1.class_id = t2.id;
-- 6. 全连接,交集 + (左表剩余内容+右表NULL) + (左表NULL+右表剩余内容)
select t1.*,t2.*
from t_student t1 full join t_class t2
on t1.class_id = t2.id;
-- 7. 合并结果集 union all,union
select t1.*,t2.*
from t_student t1 
	left outer join t_class t2 on t1.class_id = t2.id
union -- 合并结果集。会去掉重复的记录  和 全连接差不多
select t1.*,t2.*
from t_student t1 
	right outer join t_class t2 on t1.class_id = t2.id;

select t1.*,t2.*
from t_student t1 
	left outer join t_class t2 on t1.class_id = t2.id
union all -- 合并结果集。不会去掉重复的记录  
select t1.*,t2.*
from t_student t1 
	right outer join t_class t2 on t1.class_id = t2.id;
  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值