Oracle02 - Oracle语句

Oracle02 - Oracle语句

一:查询 - DQL语言

1:完整语法

-- 下面是DQL语言的完整语法
select [top | distinct] [选择列 | *]
from 数据源(表名)
[where 查询条件]
[group by 分组条件]
[having 分组过滤条件]
[order by 排序条件 asc | desc nulls first | last]

上述完整语法的执行顺序是

(1) 肯定是要先知道访问的是那个表? -> from 数据源(表名) 是最先执行的

(2) 对要筛选的行进行过滤 -> where 查询条件 是第二个执行

(3) 对过滤出来的行进行分组 -> group by 分组条件 是第三个执行的

(4) 执行分组过滤的结果 -> having 分组过滤条件 是第四个执行的

(5) 然后选择出来自己想要的列或者全部的列 -> select部分

  • 如果有distinct,会先筛选出想要的列,然后distinct
  • 如果有top, top会在select和distinct之后执行

(6) 最后是结果的输出整理 -> order by

5select [5-3TOP|5-2DISTINCT]5-1[选择列表]|[*]1from 数据源
(2[where 查询条件]3[group by 分组条件]4[having 过滤条件]6[order by asc|desc nulls first|last];

2:简单,别名和去重查询

-- 最简单的查询,连where都没有,表示将表中所有的行都获取
select * from emp;  -- 从emp表中拿到所有的数据

-- 可以为表执行别名,这在表名非常长的时候非常的有效
select e.ename from emp e; -- 给emp表起一个别名叫做e, 后续可以使用这个e来进行操作

-- 去重查询,可以对选出来的行进行去重查询
select distinct e.deptno from emp.e; -- 查看emp表中的部门编号

3:条件查询

在这里插入图片描述

-- 查询工资 > 3000 的员工的信息
select * from emp where sal > 3000; 

-- 查询工资在 3000 ~ 5000的员工的信息
select * from emp where sal between 3000 and 5001;

-- 查询家住在内蒙或者河北的员工信息
select * from emp where address = '内蒙古' or address = '河北';
-- 或者用in
select * from emp where address in ('内蒙古', '河北');

-- 查询姓张的员工
select * from emp where ename like '张%';

4:分组查询和过滤

-- 统计每一个部门有多少人
select deptno as '部门', count(*) as '人数'
from emp
group by deptno;

-- 分组过滤
-- 统计部门人数>5人的部门的编号和人数
select deptno as '部门', count(*) as '人数'
from emp
group by deptno having count(*) > 5;

5:排序查询

-- 按照员工主管编号由高到低进行排序,NULL值放到最后边
select * from emp 
order by mgr desc  # 员工编号由高到低
nulls last; # null值放到最后面

6:分页查询

-- 查询前10条员工的信息
-- 注意:Oracle中不支持limit,需要在原始表加上一列:行号,然后使用子查询来实现分页
select * 
from (select rownum hanghao,e.* from emp e) t
where t.hanghao >=1 and t.hanghao <= 10;

7:多表查询

7.1:内连接 - inner join

内连接只返回两个表中满足连接条件的行。

-- 标准写法
select 列名1, 列名2..
from1
inner join2 on1.=2.-- Oracle传统写法
select 列名1, 列名2..
from1,2
where1.=2.-- 示例
-- 标准语法
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id;

-- 传统语法
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;
7.2:外连接 - outer join

外连接返回一个表中的所有行,以及另一个表中匹配的行(如果没有匹配,则返回NULL)。

左外连接

返回左表的所有行,右表不匹配的行显示为NULL

-- 标准语法
SELECT 列名1, 列名2, ...
FROM1
LEFT OUTER JOIN2 ON1.=2.;

-- Oracle传统语法(使用+)
SELECT 列名1, 列名2, ...
FROM1,2
WHERE1.=2.(+);

-- 实例
-- 标准语法
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e
LEFT OUTER JOIN departments d ON e.department_id = d.department_id;

-- 传统语法
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id(+);

右外连接

返回右表的所有行,左表不匹配的行显示为NULL。

-- 标准语法
SELECT 列名1, 列名2, ...
FROM1
RIGHT OUTER JOIN2 ON1.=2.;

-- Oracle传统语法(使用+)
SELECT 列名1, 列名2, ...
FROM1,2
WHERE1.(+) =2.;

-- 标准语法
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e
RIGHT OUTER JOIN departments d ON e.department_id = d.department_id;

-- 传统语法
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e, departments d
WHERE e.department_id(+) = d.department_id;

全外连接

返回两个表的所有行,不匹配的行显示为NULL

-- 只有标准语法
SELECT 列名1, 列名2, ...
FROM1
FULL OUTER JOIN2 ON1.=2.;

SELECT e.employee_id, e.last_name, d.department_name
FROM employees e
FULL OUTER JOIN departments d ON e.department_id = d.department_id;
7.3:自连接 - self join

一个表与自身连接,常用于层级数据查询。

SELECT a.列名, b.列名 FROM 表 a, 表 b WHERE a.= b.;

-- 查询员工及其经理
SELECT e.employee_id, e.last_name, m.last_name AS manager_name
FROM employees e, employees m
WHERE e.manager_id = m.employee_id;
7.4:交叉连接 - cross join

返回两个表的笛卡尔积,不使用连接条件

-- 标准语法
SELECT 列名1, 列名2, ...
FROM1
CROSS JOIN2;

-- 传统语法
SELECT 列名1, 列名2, ...
FROM1,2;

-- 实例
-- 标准语法
SELECT e.last_name, d.department_name
FROM employees e
CROSS JOIN departments d;

-- 传统语法
SELECT e.last_name, d.department_name
FROM employees e, departments d;
7.5:自然连接 - natural join

自动基于相同名称的列进行连接

SELECT 列名1, 列名2, ...
FROM1
NATURAL JOIN2;

-- 实例
SELECT employee_id, last_name, department_name
FROM employees
NATURAL JOIN departments;
7.6:USING子句连接

指定用于连接的列名(列名在两个表中必须相同)

-- using子句
SELECT 列名1, 列名2, ...
FROM1
JOIN2 USING (列名);

-- 实例
SELECT employee_id, last_name, department_name
FROM employees
JOIN departments USING (department_id);

8:联合查询

  1. 列的类型要一致
  2. 列的顺序要一致
  3. 列的数量要一致,如果不够,可以使用null填充
8.1:并集运算-union

将两个查询结果进行合并

/*
	union 		: 它会去除重复的,并且排序
	union all 	: 不会去除重复的,不会排序
*/

-- 工资大于1500或者20号部门下的员工
select * from emp where sal > 1500
union
select * from emp where deptno = 20;

-- 工资大于1500或者20号部门下的员工
select * from emp where sal > 1500
union all
select * from emp where deptno = 20;
8.2:交集运算 - intersect

找两个查询结果的交集

-- 工资大于1500并且20号部门下的员工
select * from emp where sal > 1500
intersect
select * from emp where deptno = 20;
8.3:差集运算 - minus

找两个查询结果的差集

-- 1981年入职员工(不包括总裁和经理)
select * from emp where to_char(hiredate,'yyyy') = '1981'
minus
select * from emp where job = 'PRESIDENT' or job = 'MANAGER';

9:子查询

  • 单行子查询:>、>=、<、<=、!=、<>、=、<=>
  • 多行子查询:in、not in、any、some、all、exits
-- 查询所有经理的信息
select * from emp where empno in (select mgr from emp where mgr is not null);

-- 查询不是经理的信息
select * from emp where empno not in (select mgr from emp where mgr is not null);

-- 查询出比10号部门任意一个员工薪资高的员工信息
select * from emp where sal > any (select sal from emp where deptno = 10);

-- 查询出比10号部门任意一个员工薪资高的员工信息
select * from emp where sal > some (select sal from emp where deptno = 10);

-- 查询出比20号部门所有员工薪资高的员工信息
select * from emp where sal > all (select sal from emp where deptno = 20);

-- 查询有员工的部门的信息
select * from dept d1 where exists (select * from emp e1 where e1.deptno = d1.deptno);

二:Oracle函数

1:数值型函数

在这里插入图片描述

2:字符型函数

在这里插入图片描述

3:日期函数

在这里插入图片描述

4:聚组函数

在这里插入图片描述

三:数据库级别 - DCL语言

1:创建表空间

表空间是Oracle数据库中的一个重要逻辑存储结构,它是数据库对象的容器,用于组织和管理数据库中的物理存储

表空间的主要的特点

  1. 逻辑存储单元:表空间是Oracle数据库中的最高层逻辑存储结构
  2. 物理映射:一个表空间由一个或多个数据文件(Datafile)组成,这些文件是实际的物理操作系统文件
  3. 对象容器:数据库对象(如表、索引等)都存储在表空间中

表空间的构成

  • 数据文件:表空间的物理表现形式,存储在操作系统层面
  • 段(Segment):分配给特定数据库对象(如表、索引)的空间
  • 区(Extent):由一组连续的Oracle块组成,是空间分配的最小单位
  • Oracle块:数据库I/O的最小单位,通常为2KB、4KB、8KB等
-- 语法如下
create tablespace 表空间的名称
datafile '文件的路径'
size 初始化大小
autoextend on
next 每一次扩展的大小
-- 示例
create tablespace mytest
datafile 'd:/mytest.dbf'
size 100m
autoextend on
next 10m;

2:删除表空间

-- 语法
drop tablespace 表空间的名称

-- 示例
drop tablespace mytest;

3:创建用户

-- 语法
create user 用户名
indentified by 密码
default tablespace 表空间的名称

-- 示例
create user zhangsan
indentified by 123456
default tablespace mytest;

4:授权用户

系统权限分类:(系统权限只能由DBA用户授出)

  • DBA:拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构。
  • RESOURCE:拥有resource权限的用户只可以创建实体,不可以创建数据库结构。
  • CONNECT:拥有connect权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构。

实体权限分类:selectupdateinsertalterindexdeleteall

-- 语法
grant 系统权限列表 to 用户名
grant 实体权限列表 on 表名称 to 用户名

-- 示例
grant CONNECT to zhangsan; -- 只给张三登录权限
-- 或者
grant CONNECT,RESOURCE to zhangsan; -- 给张三登录和创建实体的权限
-- 或者
grant CONNECT,RESOURCE,DBA to zhangsan; -- 给张三所有的权限
-- 或者
grant DBA to zhangsan; -- 给张三所有的权限
-- 或者
grant all on emp to zhangsan; -- 给张三对于emp表的所有的权限

5:取消授权

-- 下面是取消授权(只能由DBA用户回收)
revoke 系统权限列表 from 用户名;
-- 或者
revoke 实体权限列表 on 表名称 from 用户名;


revoke CONNECT from zhangsan;
或者
revoke CONNECT,RESOURCE from zhangsan;
或者
revoke CONNECT,RESOURCE,DBA from zhangsan;
或者
revoke DBA from zhangsan;
或者
revoke all on emp from zhangsan;

6:修改密码

-- 语法
alter user 用户名 identified by "密码";

-- 演示
alter user zhangsan identified by "123456";

四:表级别 - DDL语言

先简单了解下常用的数据类型

  • 字符串类型 -> char, nchar, varchar2, nvarchar2
  • 数值类型 -> number(总位数p, 精确位数s), integer, float
  • 日期类型 -> date, timestamp

1:创建表

create table 表名(
    列名 列的类型 [列的约束],
    列名 列的类型 [列的约束]  
);

-- 示例
create table users(
     id number,
     username varchar2(20),
     password varchar2(20)
);

2:表的复制

-- 语法
create table 表名 as 查询语句;

-- 示例
create table emp_copy as (select * from emp);

3:删除表

-- 语法
drop table 表名;
truncate table 表名;

-- 演示
drop table emp_copy;
truncate table emp_copy;

4:修改表

-- 添加一列
alter table 表名 add 列名 列的类型;
alter table users add phone varchar2(11); -- 加一列phone列

-- 修改列名
alter table 表名 rename column 旧名称 to 新名称
alter table users rename column phone to mobile; -- phone列换成mobile列

-- 修改类型
alter table 表名 modify 列名 列的类型;
alter table users modify mobile char(11); -- 将mobile列变成char(11)类型的

-- 删除一列
alter table 表名 drop column 列名;
alter table users drop column mobile; -- 删除一列

-- 修改表名
rename 旧表名 to 新表名;
rename users to myusers; -- 修改表的名称是myusers

5:表的约束

CREATE TABLE 表名(
        列名 列的类型 primary key,-- 主键约束
        列名 列的类型 not null,-- 非空约束
        列名 列的类型 unique,-- 唯一约束
    	列名 列的类型 check(列名 in (检查列表)),-- 检查约束
        constraint 约束名 foreign key(字段名) references 主表(被引用列) -- 外键约束
);
-- 商品分类表
create table category(
       cid number primary key,
       cname varchar2(20) 
);

-- 商品详情表
create table product(
       pid number primary key,
       pname varchar2(50) not null,
       pimg varchar2(50) unique,
       pflag varchar2(10) check(pflag in ('上架','下架')),
       cid number,
       constraint FK_CATEGORY_ID foreign key(cid) references category(cid)
);
-- 约束修改

-- 主键约束
-- 添加
alter table product add constraint PK_PRODUCT_PID primary key(pid);
-- 删除
alter table product drop constraint PK_PRODUCT_PID;
-- 或者
alter table product drop primary key;

-- 非空约束
-- 添加
alter table product modify pname not null;
-- 删除
alter table product modify pname null;

-- 预检约束
-- 添加
alter table product add constraint CK_PRODUCT_PFLAG check(pflag in ('上架','下架'));
-- 删除
alter table product drop constraint CK_PRODUCT_PFLAG;


-- 外键约束
-- 添加
alter table product add constraint FK_PRODUCT_ID foreign key(cid) references category(cid);
-- 删除
alter table product drop constraint FK_PRODUCT_ID;

五:增删改 - DML语言

1:插入语句

insert into 表名(列名1,列名2,...) values(1,2,...);

insert into category(cid,cname) values(1,'电视');

注意:commit;

2:修改语句

update 表名 set 列名1=1,列名2=2,... where 查询条件;

update category set cname='汽车' where cid = 1;

注意:commit;

3:删除语句

delete from 表名 where 查询条件;

delete from category where cid = 1;

注意:commit;

六:事务 - TCL语言

1:事务基础

一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行

CAID

  1. 原子性:一个事务是不可再分割的整体,要么都执行要么都不执行
  2. 一致性:一个事务的执行不能破坏数据库数据的完整性和一致性
  3. 隔离性:一个事务不受其它事务的干扰,多个事务是互相隔离的
  4. 持久性:一个事务一旦提交了,则永久的持久化到本地

2:Oracle中的事务

1️⃣ 开启事务 -> Oracle 11g中事务是隐式自动开始的,它不需要用户显示的执行开始事务语句

2️⃣ 编写一组逻辑sql语句 -> sql语句支持的是insert、update、delete

3️⃣ 提交事务commit & 回滚rollback​

1、开启事务
Oracle 11g中事务是隐式自动开始的,它不需要用户显示的执行开始事务语句

2、编写一组逻辑sql语句
注意:sql语句支持的是insertupdatedelete

【设置回滚点】
savepoint 回滚点名;

3、结束事务
提交:commit;
回滚:rollback;
回滚到指定的地方: rollback to 回滚点名;

3:事务读问题

多个事务同时操作同一个数据库的相同数据时

  1. 脏读:一个事务读到了另一个事务还未提交的update数据,导致多次查询的结果不一样(Oracle中不会产生)
  2. 不可重复读:一个事务读到了另一个事务已经提交的update数据,导致多次查询结果不一致
  3. 幻读:一个事务读到了另一个事务已经提交的insert数据,导致多次查询的结果不一样

可以通过设置隔离级别解决上述并发问题

Oracle中只支持READ COMMITTEDSERIALIZABLEREAD ONLYREAD WRITE

4:事务写问题

在事务的隔离级别内容中,能够了解到两个不同的事务在并发的时候可能会发生数据的影响。

细心的话可以发现事务隔离级别章节中,脏读、不可重复读、幻读三个问题都是由事务A对数据进行修改、增加,事务B总是在做读操作。

如果两事务都在对数据进行修改则会导致另外的问题:丢失更新

悲观锁:认为两个事务更新操作一定会发生丢失更新

解决:通过在语句后边添加for update来实现行级上锁,所以又称为“行级锁”

例如:select * from t_account t wheret.id=‘1’ for update;

乐观锁:认为事务不一定会产生丢失更新,让事务进行并发修改,不对事务进行锁定

解决:由程序员自己解决,可以通过给数据表添加自增的version字段或时间戳timestamp,进行数据修改时,数据库会检测version字段或者时间戳是否与原来的一致,若不一致,抛出异常或者重新查询

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值