Oracle与MySQL的使用区别

小聊:本篇文章将介绍小白学习使用时总结的 Oeacle 使用中与 MySQL 的区别。因为大多数人都会先接触 MySQL,虽然两者都是使用 SQL 作为编程语言,大致操作数据库的过程没有太大区别。尽管如此,因为 Oracle 的数据结构不同于其它数据库,使用某些 sql 操作时写法还是会和 MySQL 不同。本文只会介绍 Oracle 的对比 MySQL 使用不一样的地方,所以需要先了解 MySQL 使用 sql 的基础, 然后结合 Oracle 理解使用,以免混淆两个数据库的使用习惯。

MySQL的sql使用,需要的话推荐《MSQL使用sql大全(完整+细节)》


1. 体系结构不同

1.1. MySQL存储结构

以 InnoDB 为例

  • 操作层次结构

1)数据库

作为关系型数据库,MySQL使用DBMS(DataBase Management System)管理操作数据库存储,SQL(Structured Query Language)作为编程语言。
可以建立多个数据库存储,在每个数据库中建立表和其它结构,每张表都有一个表空间。

2)用户

然后是用户,MySQL的最大权限用户是 root,初始就存在,还有一些其它系统用户,root 用户可以创建其它用户并赋权,层级在数据库之上,用户们根据自己的权限共同管理数据库和表。

  • 逻辑存储结构

1)表空间

InnoDB存储引擎逻辑结构的最高层,ibd文件其实就是表空间文件,每一个ibd文件就对应一张表,在表空间中可以包含多个Segment段。

2)段

表空间是由各个段组成的, 常见的段有数据段、索引段、回滚段等。InnoDB中对于段的管理,都是引擎自身完成,不需要人为对其控制,一个段中包含多个区。

3)区

区是表空间的单元结构,每个区的大小为1M。 默认情况下, InnoDB存储引擎页大小为16K, 即一个区中一共有64个连续的页。

4)页

页是组成区的最小单元,页是InnoDB存储引擎磁盘管理的最小单元,每个页的大小默认为 16KB。为了保证页的连续性,InnoDB 存储引擎每次从磁盘申请 4-5 个区。

5)行

InnoDB 存储引擎是面向行的,也就是说数据是按行进行存放的,在每一行中除了定义表时所指定的字段以外,还包含两个隐藏字段(后面会详细介绍)。


1.2. Oracle 存储结构

  • 操作层次结构

1)数据库

Oracle 数据库的概念和其它数据库不一样,这里的数据库是一个操作系统只有一个库。可以看作是 Oracle 就只有一个大数据库。一个Oracle实例(Oracle Instance)有一系列的后台进程(Backguound Processes)和内存结构(Memory Structures)组成。一个数据库可以有 n 个实例。

2)表空间

Oracle的表空间概念不同于MySQL,因为只有一个库,Oracle允许创建多个表空间来存储管理数据。表空间是 Oracle 对物理数据库上相关数据文件(ORA 或者 DBF 文件)的逻辑映射。一个数据库在逻辑上被划分成一到若干个表空间,每个表空间包含了在逻辑上相关联的一组结构。每个数据库至少有一个表空间(称之为 system 表空间)。

每个表空间由同一磁盘上的一个或多个文件组成,这些文件叫数据文件(datafile)。一个数据文件只能属于一个表空间。

3)数据文件(dbf)

数据文件是数据库的物理存储单位。数据库的数据是存储在表空间中的,真正是在某一个或者多个数据文件中。而一个表空间可以由一个或多个数据文件组成,一个数据文件只能属于一个表空间。一旦数据文件被加入到某个表空间后,就不能删除这个文件,如果要删除某个数据文件,只能删除其所属于的表空间才行。

4)用户

Oracle的最大权限用户是system,初始存在。用户是在表空间下建立的。用户登陆后只能看到和操作自己的表, ORACLE 的用户与 MYSQL 的数据库类似,每建立一个应用需要创建一个用户。

表的数据,是由用户放入某一个表空间的,而这个表空间会随机把这些表数据放到一个或者多个数据文件中。
由于 oracle 的数据库不是普通的概念,oracle 是有用户和表空间对数据进行管理和存放的。但是表不是有表空间去查询的,而是由用户去查的。因为不同用户可以在同一个表空间建立同一个名字的表!这里区分就是用户了!

在这里插入图片描述

  • 逻辑存储结构

在这里插入图片描述

  • 总结

Oracle 数据库和 MySQL 数据库有所不同,可以把Oracle比作镜像,它可以生成多个数据库实例(就是后台进程,也就是说我们安装了一个数据库应用却可以启动多个实例,一般不这么做,只是说明一下它可以这么做);每一个实例相当于一个数据库,而它只能有一个数据库,可以有多个表空间;与MySQL不同,MySQL可以有多个用户并且由Root用户创建并分配数据库及表操作权限,而Oracle是在表空间层级上创建用户,在给用户分配操作该表空间的数据表的权限;表空间按照存贮又可以有区、段、数据块等层级,但是数据实际是存在数据文件(①dbf/ora)中的,只是我们间接的使用了表空间去操作数据文件。

因为ORacle这种独有的数据结构,Oracle引入表空间的概念有利于Oracle数据的管理,它的思想是“一个表空间是一个逻辑单位,但是它管理着很多的物理单位”,为什么呢?因为这些物理文件是可以分配到不同的服务器上,这样的话就可以用多个服务器减轻一个Oracle数据库磁盘的整体压力了,如果像MySQL要使用多个服务器的话只能去实现水平垂直分库或者读写分离。而不管我数据文件是存储在哪里,我Oracle始终操作的只有一个表空间。表空间的设计也是Oracle强大的体现之一。

(注①:ORACLE8i 之前数据文件的后缀名为 .ora,之后为 .dbf ;无论 .ora.dbf,实际使用没任何区别,也可以不用扩展名或指定任意扩展名,只是通过扩展名来标识文件的类型而已。所以对于数据文件不管是 ora/dat/dbf,都是一样的,没有什么区别)


2. 以下是Oracle使用sql语句的区别

3. DDL(数据定义语言)

3.1. Oracle创建表空间

oracle独有的表空间,Mysql没有

create tablespace waterboss
datafile 'c:\waterboss.dbf'
size 100m
autoextend on
next 10m

waterboss 为表空间名称

datafile 用于设置物理文件名称

size 用于设置表空间的初始大小

autoextend on 用于设置自动增长,如果存储量超过初始大小,则开始自动扩容

next 用于设置扩容的空间大小


3.2. Oracle建表特有字段类型

  • 字符型

Oracle 有 char、varchar2、nuarchar2的字符类型,通常建议使用 varchar2

类型名 字节大小 默认字节大小 说明
char() 0 ~ 2000 1 定长字符串,会用空格填充来达到器最大长度,如果长度超出了就会报错。
varchar2() 0 ~ 4000 1 变长字符串,在存数据的时候,给的数据占不满给定的空间会自动截断,省空间。
如果长度超出了会补长,不会报错;
并且它将原本varchar可以存储空字符串的特性转换成了可以存储null值,提供了向后兼容的能力;
nuarchar2() 0 ~ 4000 2 包含unicode格式数据的变长字符串,一个空间占用2个字节,最大长度是 NCHAR 的两倍。
长度并不是表示字节数了,而是字符数量。比如 nuarchar2(10) 表示可以存储10个字符

拓展问答:

问:为什么不直接全部使用varchar2呢?

答:1)VARCHAR2虽然比CHAR节省空间,但是假如一个VARCHAR2列经常被修改,而且每次被修改的数据的长度不同,这会引起‘行迁移’(RowMigration)现象,而这会造成多余的I/O,是数据库设计和调整中要尽力避免的,在这种情况下用CHAR代替VARCHAR2会更好一些;

2)还有就是当我们存储已知固定长度的数据时,比如:手机号(11位)、身份证号码(18位)等,可以考虑使用 char。因为,在查询数据时,对于 char 类型字段,是全字符整体匹配;而 varchar2 是一个字符一个字符的进行匹配;

3)并且char的效率要比varchar2高一些,为了提高效率就必须牺牲一些空间。

  • 数字类型
类型名 说明
number 在Oracle中取消了在 mysql 中的 int 类型,使用 number 代替,如果你在创建数据库表的时候使用了 int 类型会自动转换成 number 类型,并且 Oracle 没有这个 “auto_increment” 属性,所以它没法像 MySQL 般在表内定义自增主键。但是,Oracle 里的序列(SEQUENCE),可间接实现自增主键的作用。
number(p,s) p 是 precison 的英文缩写,即精确缩写,表示有效数字的位数,最多不能超过38个有效数字;
s 是 scale 的英文缩写,表示小数点数字的位数,多出来的位数要四舍五入。
  • 浮点型
类型名 默认字节大小 说明
binary_float 32 单精度浮点数字数据类型。可以支持至少6位精度,每个 binary_float 的值需要5个字节,包括长度字节。
binary_double 64 双精度浮点数字数据类型。每个 binary_double 的值需要9个字节,包括长度字节。

3.3. Oracle没有auto_increment属性

解决:使用序列和触发器。

使用示例

-- 1.建立一个表,menuId是需要自增的字段
create table menu( 
menuId number(10) not null primary key,
name varchar2(40) not null,
id_parent number(10) not null,
);

-- 2.然后建立一个序列,最小值是minvalue,最大值是maxvalue,从1开始,步进为1递增,无循环,无缓存。
-- 关于create sequence的详细用法。
create sequence menu_autoinc_seq
minvalue 1
maxvalue 999999999
start with 1
increment by 1
nocycle;

-- 3.然后建立一个触发器,在插入tun_menu表之前触发,选取序列的nextval作为新值。
-- 关于create trigger的详细用法。
create or replace trigger menu_autoinc_tg
before insert on menu
for each row
begin
select menu_autoinc_seq.nextval into :new.menuId from dual;
end menu_autoinc_tg;

-- 4.最后检验成果,看是否能让字段自动增加,向menu表中添加数据,无论menuId是什么值都会被替换掉
insert into menu values(null, '宫保鸡丁',1);
insert into menu values(null, '红烧茄子',6);
insert into menu values(null, '麻辣香锅',3);

3.4. Oracle引号使用区别

  • MySQL

1)单引号:将字符串常量括起来,若常量本身带有单引号,除了转义功能,还可以使用双引号整体括起;

'student' 
stu'dent转义: 'stu\'dent' 或 'stu''dent'(单引号对其转义)
stu'dent双引号括起: "stu'dent" 

2)双引号:将字符串常量括起来,若常量本身带有双引号,除了转义,还可以使用单引号整体括起;

say:"Hello"的转义: "say:\"Hello\"""say:""Hello"""(两个双引分别转义)
say:"Hello"单引号括起: 'say:"Hello"'

mysql中双引号引用在某些版本中会报错,为了避免,尽量使用单引号来操作字符串。

3)反引号:区别保留字(就是关键字)与普通字符的符号;

create table desc;   报错
create table `desc`; 创建成功

即使表名和字段名不是数据库保留字,尽可能也养成加上反引号的好习惯,这也可以避免错误,保证开发的顺利进行

  • Oracle

1)单引号:将字符串常量括起来;

2)双引号:强制区分大小写,就是 Oracle 同样支持小写;

CREATE TABLE "StUdEnT" (...);
# 建表时使用双引号严格指定大小写,在查询时就要使用相同的方式,如下,否则报错
SELECT * FROM "StUdEnT";

3)反引号:不存在


3.5. Oracle不存在:“drop table if exists”

Mysql 创建表之前判断表是否存在,如果存在则删除已有表

DROP TABLE IF EXISTS tableName;

设置触发器,Oracle 创建表之前判断表是否存在,如果存在则删除已有表

declare  -- 声明
      num number; -- 定义变量
begin  -- 开始
    select count(1) into num from user_tables where table_name = upper('tableName');  -- 给自己定义的变量赋值
    if num > 0 then	-- 语法
        execute immediate 'drop table tableName' ;
    end if;
end; -- 结束

这样挺麻烦的,省事一点的话直接查一遍看看有没有再创建。


4. DML(数据操纵语言)

4.1. oracle不可以批量插入

  • MySQL一次性添加多条数据
insert into 表名 (字段名1, 字段名2, 字段名3) values (1,2,3), (1,2,3), (1,2,3) .....;
  • Oracle 不可以一次性添加多条数据,会报错,只能一条 insert 添加一行数据
insert into department values(null, '指挥部'),(null, '侦查部');
报错:ORA-00933: SQL command not properly ended
insert into department values(null, '指挥部');
insert into department values(null, '侦查部');
执行成功!

5. DQL(数据查询语言)

5.1. Oracle基于伪列的查询——ROWID

在 Oracle 的表的使用过程中,实际表中还有一些附加的列,称为伪列。伪列就 像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。

表中的每一行在数据文件中都有一个物理地址,ROWID 伪列返回的就是该行的 物理地址。使用 ROWID 可以快速的定位表中的某一行。ROWID 值可以唯一的 标识表中的一行。由于 ROWID 返回的是该行的物理地址,因此使用 ROWID 可 以显示行是如何存储的。

  • 举例
select t.ROWID, t.* from GIRL t;

在这里插入图片描述

  • 我们可以通过指定 ROWID 来查询记录
select t.ROWID, t.* from GIRL t; where ROWID='AAAM1fAAGAAAAAuAAA';

在这里插入图片描述

注意:当我们在查询sql中添加了 xxx.rowid 查询字段才可以在图形化结果表中直接进行图形化键盘输入更新操作,比如说:

select r.* from role r;  # 不可修改图形化返回结果表
select r.rowid, r.* from role r; # 解锁后,可修改图形化返回结果表



5.2. Oracle基于伪列的查询——ROWNUM

在查询的结果集中, ROWNUM 为结果集中每一行标识一个行号,第一行返回 1, 第二行返回 2,以此类推。通过 ROWNUM 伪列可以限制查询结果集中返回的行数。

  • 举例
select rownum, g.* from GIRL g;

在这里插入图片描述


5.3. Oracle的外连接查询

Oracle的外联查询语法除了支持正常的SQL1999标椎语法的 left/right join 之外,还提供一种带 + 的超直观方便的查询方式,MySQL不支持。

  • SQL1999标椎语法外连接查询
-- outer 可以省略
select 字段名 from 左表 left [ outer ] join 右表 on 条件;  # 左外连接查询
select 字段名 from 左表 right [ outer ] join 右表 on 条件;  # 右外连接查询
  • Oracle独有方式查询
select 字段名 from 左表 a, 右表 b, where a.属性 = b.属性(+);  # 左外连接查询
select 字段名 from 左表 a, 右表 b, where a.属性(+) = b.属性;  # 右外连接查询

记住 + 的顺序不要搞错了,诀窍是:左外连接查询需要保证左表数据全部显示,右边数据进行补充,所以要在右表的条件上添加 +;同理右外连接查询也是如此记忆。


5.4. Oracle分页和排序分页查询

因为Oracle没有 limit 关键字,所以分页的实现需要用别的方式进行sql的编写,要用到的就是 rowsum,上面有过它的介绍。

  • 查询表的前五条数据
select rownum,t.* from users t where rownum<=5;

在这里插入图片描述

  • 查询表的第6条到第10数据
-- select rownum,t.* from users t where rownum>5 and rownum<=10; -- 错误sql,查询无结果
-- 子查询方式实现
select * from 
(select rownum r,t.* from users t where rownum<=10) 
where r>5;

在这里插入图片描述

为什么第一条sql无结果?

这是因为 rownum 是在查询语句扫描每条记录时产生的,所以不能使用“大于” 符号,只能使用“小于”或“小于等于” ,只用“等于”也不行。

  • 基于排序的分页查询:查询按age降序后的第5到第10条记录
 -- 错误SQL,结果没有按要求正确排序
select * from (select rownum r, t.* from users t where rownum<=10 order by age desc) where r>5 ;

在这里插入图片描述

为什么没有正常排序?

因为 ROWNUM 伪列的产生是在表记录扫描的时候产生的,而排序是后进行的,排序时 ROWNUM 已经产生了,所以排序后 ROWNUM 是乱的。所以需要先排好序在从排好序的表中取分页数据(注意。这里需要给子查询中的 rownum 取别名用作查询条件)

-- 正确sql:第一种方式:三层嵌套查询
select * from 
(select rownum r,t.* from (select * from users order by age desc) t where rownum<=10) 
where r>5

在这里插入图片描述

-- 正确sql:第二种方式:使用分析函数ROW_NUMBER,用 row_number()分析函数实现的分页查询相对三层嵌套子查询要简单,只有两层查询
select * from 
(select row_number() over(order by age desc) rownumber, t.* from users t) 
where rownumber>5 and rownumber<=10

在这里插入图片描述


6. DCL(数据控制语言)

因为oracle的用户是基于表空间创建的,所以我们在用户操作时需要指定表空间。Mysql是没有这样的概念的,如果想看sql对比,请移步《MySQL使用sql大全》

6.1. 创建用户

create user wateruser
identified by abc
default tablespace waterboss

wateruser 为创建的用户名

identified by 用于设置用户的密码

default tablesapce 用于指定默认表空间名称


6.2. 修改用户

alter user wateruser
identified by ABC
default tablespace waterboss

wateruser 为创建的用户名

identified by 用于设置用户的密码

default tablesapce 用于指定默认表空间名称


6.3. 删除用户

drop user wateruser

wateruser 为要删除的用户名


6.4. 用户赋权

oracle 提供三种标准角色(role):connectresourcedba.

  • connect role(连接角色)

临时用户,特指不需要建表的用户,通常只赋予他们connect role
connect 是使用 oracle 简单权限,这种权限只对其他用户的表有访问权限,包括 select/insert/update和delete 等。
拥有 connect role 的用户还能够创建表、视图、序列(sequence)、簇(cluster)、同义词(synonym)、回话(session)和其他 数据的链(link)。

  • resource role(资源角色)

更可靠和正式的数据库用户可以授予 resource role。
resource 提供给用户另外的权限以创建他们自己的表、序列、过程(procedure)、触发器(trigger)、索引(index)和簇(cluster)

  • dba role(数据库管理员角色)

dba role 拥有所有的系统权限
包括无限制的空间限额和给其他用户授予各种权限的能力。

  • 系统权限分类
权限 说明
DBA 拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构。
RESOURCE 拥有Resource权限的用户只可以创建实体,不可以创建数据库结构。
CONNECT 有Connect权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构。
  • 使用

对于普通用户:授予 connect, resource 权限。

对于DBA管理用户: 授予 connect,resource, dba 权限。

  • 使用示例
grant connect, resource to wateruser;
grant dba to fireuser

给用户 wateruser 赋予 connect 和 resource 权限;给用户 fireuser 赋予 DBA 权限


6.5. 用户撤权

revoke connect, resource from wateruser;
revoke dba from fireuser

撤销用户 fireuser 被赋予的 connect 和 resource 权限;撤销用户 fireuser 被赋予的 DBA 权限


6.6. 查询用户

查询所有用户

select * from all_users;

7. 单行函数

  • 用处

1)查看当前用户各种信息

2)用来调用系统函数

7.1. 伪表dual

也叫虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。
简单来说, dual表就是oracle与数据字典自动创建的一张表,这张表是一个单行单列的表,这个表只有1列: DUMMY,数据类型为VERCHAR2(1),dual表中只有一个数据X,Oracle有内部逻辑保证dual表中永远只有一条数据。dual表主要是用来选择系统变曩或是求一个表达式的值。

select d.rowid, d.* from dual d;

在这里插入图片描述

  • 使用dual查询(举例)

1)获得当前系统时间

select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

2)获得主机名

select SYS_CONTEXT('USERENV','TERMINAL') from dual;

3)获得当前 locale

elect SYS_CONTEXT('USERENV','language') from dual;

4)获得一个随机数

select dbms_random.random from dual;

5)序列运算,我们在设置自增的时候用到过

select your_sequence.nextval from dual; -- 获得序列 your_sequence的下一个值
select your_sequence.currval from dual; -- 获得序列your_sequence的当前值

6)可以用做计算器运算

select 7*9 from dual;

7.2. 字符函数

  • 作用

可以利用字符函数对 sql 查询结果值进行运算修饰然后返回最后需要业务的结果。

当然,MySQL也有类似的函数,这里我们只讲Oracle,为了方便,使用dual虚拟表作为演示,实际可以查询真正的表对其返回结果做运算。

函数 说明
ASCII 返回对应字符的十进制值
CHR 给出十进制返回字符
CONCAT 拼接两个字符串,与 || 相同
INITCAT 将字符串的第一个字母变为大写
INSTR 找出某个字符串的位置
INSTRB 找出某个字符串的位置和字节数
LENGTH 以字符给出字符串的长度
LENGTHB 以字节给出字符串的长度
LOWER 将字符串转换成小写
LPAD 使用指定的字符在字符的左边填充
LTRIM 在左边裁剪掉指定的字符
RPAD 使用指定的字符在字符的右边填充
RTRIM 在右边裁剪掉指定的字符
REPLACE 执行字符串搜索和替换
SUBSTR 取字符串的子串
SUBSTRB 取字符串的子串(以字节)
SOUNDEX 返回一个同音字符串
TRANSLATE 执行字符串搜索和替换
TRIM 裁剪掉前面或后面的字符串
UPPER 将字符串变为大写
  • 常用字符函数举例

(1)求字符串长度 LENGTH

select length('ABCD') from dual;
-- 结果:4

(2)求字符串的子串 SUBSTR

select substr('ABCD',2,2) from dual;
-- 结果:BC

(3)字符串拼接 CONCAT

select concat('ABC','D') from dual;
-- 结果:ABCD
-- 也可以用 || 对字符串进行拼
select 'ABC'||'D' from dual;
-- 结果:ABCD

(4)找出字符串位置 INSTR:

select INSTR('abcdbc', 'b', 1, 1) from dual; -- 原字符串;要查找的字符串;查找初始位置;查找第几个。返回子字符串索引
-- 结果:2

7.3. 数值函数

函数 说明
ABS(value) 绝对值
CEIL(value) 大于或等于 value 的最小整数
COS(value) 余弦
COSH(value) 反余弦
EXP(value) e 的 value 次幂
FLOOR(value) 小于或等于 value 的最大整数
LN(value) value 的自然对数
LOG(value) value 的以 10 为底的对数
MOD(value,divisor) 求模
POWER(value,exponent) value 的 exponent 次幂
ROUND(value,precision) 按 precision 精度 4 舍 5 入
SIGN(value) value 为正返回 1;为负返回-1;为 0 返回 0.
SIN(value) 余弦
SINH(value) 反余弦
SQRT(value) value 的平方根
TAN(value) 正切
TANH(value) 反正切
TRUNC(value,按 precision) 按照 precision 截取 value
VSIZE(value) 返回 value 在 ORACLE 的存储空间大小
  • 常用字符函数举例

  • (1)四舍五入函数 ROUND

    select round(100.567) from dual;
    -- 结果:101
    select round(100.567, 2) from dual; -- 保留两位小数
    -- 结果:100.57
    
  • (2)截取函数 TRUNC

    select trunc(100.567) from dual; -- 去整
    -- 结果:100
    select trunc(100.567, 2) from dual; -- 保留两位小数
    -- 结果:100.56
    
  • (3)取模 MOD

    select mod(10, 3) from dual;
    -- 结果:1
    

7.4. 日期函数

函数 说明
ADD_MONTHS 在日期 date 上增加 count 个月
GREATEST(date1,date2,. . .) 从日期列表中选出最晚的日期
LAST_DAY( date ) 返回日期 date 所在月的最后一天
LEAST( date1, date2, . . .) 从日期列表中选出最早的日期
MONTHS_BETWEEN(date2, date1) 给出 Date2 - date1 的月数(可以是小数)
NEXT_DAY( date,’day’) 给出日期 date 之后下一天的日期,这里的 day 为星期,如: MONDAY,Tuesday 等。
NEW_TIME(date,’this’, ’other’) 给出在 this 时区=Other 时区的日期和时间
ROUND(date,’format’) 未指定 format 时,如果日期中的时间在中午之前,则将日期中的时间截断为 12 A.M.(午夜,一天的开始),否则进到第二天。时间截断为 12 A.M.(午夜,一天的开始),否则进到第二天。
TRUNC(date,’format’) 未指定 format 时,将日期截为 12 A.M.( 午夜,一天的开始).

我们用 sysdate 这个系统变量来获取当前日期和时间,语句如下:

select sysdate from dual;
-- 结果:2022/11/12 1:24:14
  • 常用字符函数举例

(1)加月函数 ADD_MONTHS :在当前日期基础上加指定的月

select add_months(sysdate, 2) from dual;
-- 结果:2023/1/12 1:26:35

(2)求所在月最后一天 LAST_DAY

select last_day(sysdate) from dual;
-- 结果:2022/11/30 1:27:51

(3)日期截取 TRUNC

select TRUNC(sysdate) from dual;
-- 结果:2022/11/12

select TRUNC(sysdate,'yyyy') from dual;
-- 结果:2022/1/1

select TRUNC(sysdate,'mm') from dual;
-- 结果:2022/11/1

7.5. 转换函数

函数 描述
CHARTOROWID 将 字符转换到 rowid 类型
CONVERT 转换一个字符节到另外一个字符节
HEXTORAW 转换十六进制到 raw 类型
RAWTOHEX 转换 raw 到十六进制
ROWIDTOCHAR 转换 ROWID 到字符
TO_CHAR 转换日期格式到字符串
TO_DATE 按照指定的格式将字符串转换到日期型
TO_MULTIBYTE 把单字节字符转换到多字节
TO_NUMBER 将数字字串转换到数字
TO_SINGLE_BYTE 转换多字节到单字节
  • 常用字符函数举例

(1)数字转字符串 TO_CHAR

select TO_CHAR(1024) from dual;
-- 结果:1024

(2)日期转字符串 TO_CHAR

select TO_CHAR(sysdate,'yyyy-mm-dd') from dual;
-- 结果:2022-11-12

(3)字符串转日期 TO_DATE

select TO_DATE('2022-09-13','yyyy-mm-dd') from dual;
-- 结果:2022/9/13

(4)字符串转数字 TO_NUMBER

select to_number('100') from dual;
-- 结果:100

7.6. 分析函数

函数 描述
RANK 相同的值排名相同,排名跳跃。
DENSE_RANK 相同的值排名相同,排名连续
ROW_NUMBER 返回连续的排名,无论值是否相等。
  • 函数使用举例

(1)相同的值排名相同,排名跳跃

select t.*, rank() over(order by age desc) 年龄排名 from users t;

在这里插入图片描述

(2)相同的值排名相同,排名连续

select t.*, dense_rank() over(order by age desc) 年龄排名 from users t;

在这里插入图片描述

(3)返回连续的排名,无论值是否相等

select t.*, row_number() over(order by age desc) 年龄排名 from users t;

在这里插入图片描述


7.7. 其它函数

函数 描述
NVL NVL(检测的值,如果为null的值);
NVL2 NVL2(检测的值,如果不为 null 的值,如果为 null 的值);
DECODE decode(条件, 值 1, 翻译值 1, 值 2, 翻译值 2, …值 n, 翻译值 n, 缺省值); 说明:根据条件返回相应值
  • 函数使用举例

(1)空值处理函数 NVL

select NVL(NULL, 0) from dual;
-- 结果:0

(2)空值处理函数 NVL2

select NVL2(NULL, '有值', '空') from dual;
-- 结果:空

(3)条件取值 decode

select decode(3, 1, '晴天', 2, '阴天', 3, '雨天', 666) from dual;
-- 结果:雨天

随笔

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_48489737/article/details/127823273