2024-03-05 19:19:39 +08:00

859 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Oracle
date: 2021-03-23 10:30:31
author: 文永达
---
# Oracle Database
## 安装Oracle 19c
### Linux下安装
#### rpm方式
从Oracle官网下载安装包 Linux x86-64 RPM
https://www.oracle.com/database/technologies/oracle-database-software-downloads.html
![image-20240226135109613](Oracle/image-20240226135109613.png)
安装帮助文档
https://docs.oracle.com/en/database/oracle/oracle-database/19/ladbi/preface.html#GUID-071A6B76-11E3-4421-963E-41DA6F2EF07A
下载 `preinstall` 下载地址
https://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/index.html浏览器搜索-19c
或者
```shell
curl -o oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm https://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackage/oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm
```
安装,首先执行
```shell
yum localinstall -y oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm
```
会提示缺少依赖
可以去RPM源网站下载
http://www.rpmfind.net/linux/rpm2html/search.php?query=compat-libcap1(x86-64)
安装
```shell
rpm -ivh compat-libcap1-1.10-7.el7.x86_64.rpm
```
再次执行
```shell
yum localinstall -y oracle-database-preinstall-19c-1.0-3.el7.x86_64.rpm
```
安装数据库
```shell
yum localinstall -y oracle-database-ee-19c-1.0-1.x86_64.rpm
```
配置数据库
```shell
/etc/init.d/oracledb_ORCLCDB-19c configure
```
过程较长,等待即可
可能会JDK报错
```shell
yum install libnsl
```
配置完成后设置当前用户下的环境变量
```shell
vim /etc/profile.d/oracle19c.sh
export ORACLE_HOME=/opt/oracle/product/19c/dbhome_1
export PATH=$PATH:/opt/oracle/product/19c/dbhome_1/bin
export ORACLE_SID=ORCLCDB
# 保存退出,执行
source /etc/profile.d
```
验证安装是否正确
```shell
passwd oracle
su oracle
sqlplus / as sysdba
# 提示
SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 17 12:25:27 2022
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to an idle instance.
```
启动监听
![image-20221017123327552](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221017123327552.png)
#### Docker方式
安装Docker
```shell
sudo wget -qO- https://get.docker.com/ | bash
docker --version
systemctl start docker
systemctl status docker
systemctl enable docker
```
拉取镜像 `quay.io/maksymbilenko/oracle-12c`
```shell
docker pull quay.io/maksymbilenko/oracle-12c
```
如果有本地镜像则使用
```shell
docker build -t quay.io/maksymbilenko/oracle-12c .
```
构建容器
```shell
# 首先创建本地目录
mkdir /oracle/data
# 授予权限
chmod -R 777 /oracle/data
docker run --name o12c -d -p 8080:8080 -p 1521:1521 -v /oracle/data:/u01/app/oracle quay.io/maksymbilenko/oracle-12c
# 查看日志
docker logs -f # 字符串ID
```
![image-20221017145702216](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221017145702216.png)
安装完成
数据库连接信息
```yaml
hostname: localhost
port: 1521
sid: xe
service name: xe
username: system
password: oracle
```
进入容器修改账号密码设置
```shell
# 查看所有容器信息
docker ps -a
docker exec -it [containerID] /bin/bash
# 切换成oracle用户
su oracle
# 进入sqlplus
$ORACLE_HOME/bin/sqlplus / as sysdba
SQL*Plus: Release 12.1.0.2.0 Production on Sun Aug 1 03:15:37 2021
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
# 设置密码有效期为无限制
SQL> ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;
Profile altered.
SQL> alter user SYSTEM account unlock;
User altered.
# 创建一个账号为act_test的用户密码设置为test
SQL> create user act_test identified by test;
User created.
# 为这个用户赋予管理员的权限
SQL> grant dba to act_test;
Grant succeeded.
# ctrl + p + q 退出容器注意不要exit退出防止容器直接关闭了
```
## Oracle SQL Developer
### 设置自动提示
工具栏 -> 工具 -> 首选项 -> 代码编辑器 -> 完成设置
![image-20221017111632399](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221017111632399.png)
### 设置代码模板
工具栏 -> 工具 -> 首选项 -> 代码编辑器 -> 代码模板
![image-20221017112825105](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221017112825105.png)
### 同时打开多个表
工具栏 -> 工具 -> 首选项 -> 数据库 ->对象查看器
![image-20221020141231505](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221020141231505.png)
## SQL PLUS
### 解决乱码
```shell
sqlplus / as sysdba
col parameter for a30
col value for a25
select * from nls_database_parameters;
PARAMETER VALUE
------------------------------ -------------------------
NLS_RDBMS_VERSION 19.0.0.0.0
NLS_NCHAR_CONV_EXCP FALSE
NLS_LENGTH_SEMANTICS BYTE
NLS_COMP BINARY
NLS_DUAL_CURRENCY $
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM
TZR
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_FORMAT HH.MI.SSXFF AM
PARAMETER VALUE
------------------------------ -------------------------
NLS_SORT BINARY
NLS_DATE_LANGUAGE AMERICAN
NLS_DATE_FORMAT DD-MON-RR
NLS_CALENDAR GREGORIAN
NLS_NUMERIC_CHARACTERS .,
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_CHARACTERSET AL32UTF8
NLS_ISO_CURRENCY AMERICA
NLS_CURRENCY $
NLS_TERRITORY AMERICA
NLS_LANGUAGE AMERICAN
```
`NLS_LANG`的组成规则为 `NLS_LANGUAGE_NLS_TERRITORY.NLS_CHARACTERSET`
```shell
vim ~/.bash_profile
export NLS_LANG="AMERICAN_AMERICA.AL32UTF8"
```
### 解决控制台输错命令删除
使用`Ctrl + backspace`代替`backspace`
### 登录
```shell
# 以oracle账号登录
su oracle
$ORACLE_HOME/bin/sqlplus / as sysdba
```
### 修改sys密码
```shell
sqlplus /nolog
conn as sysdba
alter user sys identified by 123456;
```
## CDB 和 PDB
- CDB :容器数据库,名称为 CDB$ROOT。其作用就是系统数据库sys等账号都保存在里面。同时它可以管理PDB数据库
- PDB 可插拔的数据库。用户可以在PDB自建数据库
- Oracle安装成功后有个默认的pdb数据库在安装Oracle的时候自己设定
- PDB中自带有PDB$SEED属于PDB的模板数据库自己创建数据库的时候以此库为模板
命令如何查看当前的位置是CDB还是PDB使用sys登录输入命令
```she
show con_name; -- 查看当前所在容器位置
show pdbs; -- 查看所有的PDB
alter pluggable database pdb1 open; -- 打开 pdb1 pdb
alter pluggable database pdb1 close immediate; -- 立刻关闭 pdb1
alter pluggable database all open; -- 打开 所有 pdb
alter session set container=cdb$root; -- pdb切换到cdb
alter session set container=pdb1; -- cdb切换到pdb1
-- 查看 cdb、pdb 信息
select name , cdb from v$database;
select name,con_id from v$services;
select name,con_id,open_mode from v$pdbs;
```
由于安装Oracle的时候设定PDB数据库为schooldb故查询到两个PDB数据库
## 表空间
### 概述
1. 表空间
1. 表空间是一个逻辑的概念,真正存放数据的是数据文件(data files)
2. 1 个数据库 = N 个表空间(N >= 1)
1 个表空间 = N 个数据文件(dbf)N >= 1
-- 1个数据文件(dbf) 只能属于 1 个表空间
2. 建立表空间的作用
1. 控制数据库占用 '磁盘空间' 的大小
2. 不同类型的数据存储到不同的位置,有利于提高 'I/O' 性能,同时有利于备份和恢复等操作
### 相关视图
```sql
-- 数据文件
select * from dba_data_files;
select * from dba_temp_files;
-- 表空间
select * from dba_tablespaces;
select * from dba_free_space;
-- 权限
select distinct t.privilege
from dba_sys_privs t
where t.privilege like '%TABLESPACE%';
select t.tablespace_name, -- 表空间
t.file_name, -- 文件名
t.autoextensible, -- 是否自增
t.bytes / 1024 / 1024 "SIZE(M)", -- 初始值
t.increment_by * 8 / 1024 "NEXT(M)", -- 步长 1blok = 8KB
t.maxbytes / 1024 / 1024 "MAXSIZE(M)" -- 最大值
from dba_data_files t;
```
![image-20240229151409259](Oracle/image-20240229151409259.png)
### 修改
```sql
-- 1 修改数据文件的大小为 20M
alter database datafile 'D:\Oracle\TBS01.dbf'
resize 20m;
-- 2 修改数据文件为自动扩展,最大值为 1G
alter database datafile 'D:\Oracle\TBS01.dbf'
autoextend on next 20m maxsize 1g;
-- 3 新增数据文件
alter tablespace "TBS01"
add datafile 'D:\Oracle\TBS01_1.dbf'
size 200m;
```
## 语法
### 新建表空间
```sql
CREATE TABLESPACE ACT_DEV
DATAFILE
'\oracle\data\oradata\xe\FILE_SPECIFICATION1.dbf' SIZE 52428800 AUTOEXTEND ON NEXT 52428800 MAXSIZE 2147483648
EXTENT MANAGEMENT LOCAL;
```
### 新建用户
```shell
# cdb下
CREATE TABLESPACE ACT_DEV
DATAFILE
'/opt/oracle/oradata/ORCLCDB/act_dev.dbf' SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
create user C##act_dev identified by 123456 default tablespace ACT_DEV;
grant dba,connect to C##act_dev;
commit;
```
### 解除占用
```sql
select l.session_id,o.owner,o.object_name
from v$locked_object l,dba_objects o
where l.object_id=o.object_id;
SELECT sid, serial#, username, osuser FROM v$session where sid = sid;
alter system kill session 'sid,serial#';
```
### 修改表
```sql
-- 表重命名
ALTER TABLE BOOK
RENAME TO BIND_PHONE_NUMBER;
-- 添加表字段Column
ALTER TABLE BIND_PHONE_NUMBER
ADD (USERNAME VARCHAR2(20) );
-- 修改表字段Column名
ALTER TABLE BIND_PHONE_NUMBER RENAME COLUMN NAME TO APPNAME;
```
### 使用关键字做完表名,列名
使用双引号""形式,如"INDEX"
### 删除表数据
```sql
TRUNCATE TABLE 表名
-- or
DELETE FROM 表名
```
### 从其他表中复制数据到插入一张表中
```sql
-- 标准语法
INSERT INTO table2
SELECT * FROM table1;
-- 多表插入到一张表 示例,ID为GUID,
-- 需要注意的是如果指定插入到哪些列中不是根据后面SELECT的列的别名来插入而是通过列的顺序插入语句后可接WHERE条件
INSERT INTO table1(ID,NAME,TEXT) SELECT SYS_GUID(), t2.NAME, t3.TEXT FROM DUAL, TABLE2 t2, TABLE3 t3;
```
## 内连接与外连接
### 内连接
合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行
语法:
```sql
SELECT 字段列表
FROM A表 INNER JOIN B表
ON 关联条件
WHERE 条件;
```
类似于:
```sql
方式一
SELECT e.employee_id, e.last_name, e.department_id,
d.department_id, d.location_id
FROM employees e JOIN departments d
ON (e.department_id = d.department_id);
方式二:
SELECT employee_id,department_name
FROM employees e,departments d
WHERE e.`department_id` = d.department_id;
```
这种查询方式它会把所有的符合where条件的字段查询出来。但是有这样一种情况就是两张表的数据有的不存在某种关系。
缺点:如果我们想要把不满足条件的数据也查询出来,内连接就做不到。
于是引入外连接。
### 外连接
查询多表时一般要求中出现:查询所有的数据时,就一定会用到外连接。
两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右)外连接。没有匹配的行时,结果表中相应的列为空(NULL)。
#### 满外连接
`FULL JOIN`
`LEFT JOIN UNION RIGHT JOIN`
#### 左外连接
语法:
```sql
SELECT 字段列表
FROM A表 LEFT JOIN B表
ON 关联条件
WHERE 条件;
```
类似于:
```sql
SELECT e.last_name, e.department_id, d.department_name
FROM employees e
LEFT OUTER JOIN departments d
ON (e.department_id = d.department_id) ;
```
`employees`表中的数据会全部显示出来
#### 右外连接
语法:
```sql
SELECT 字段列表
FROM A表 RIGHT JOIN B表
ON 关联条件
WHERE 条件;
```
类似于:
```sql
SELECT e.last_name, e.department_id, d.department_name
FROM employees e
RIGHT OUTER JOIN departments d
ON (e.department_id = d.department_id) ;
```
`departments`表中的数据会全部显示出来
### UNION的使用
·语法:
```sql
SELECT column,... FROM table1
UNION [ALL]
SELECT column,... FROM table2
```
UNION 操作符返回两个查询的结果集的并集,去除重复记录。
UNION ALL操作符返回两个查询的结果集的并集。对于两个结果集的重复部分不去重。
## Oracle 函数
### NVL()
![image-20230228133334777](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20230228133334777.png)
```sql
SELECT a.OSPREQID,a.OSPREQNO FROM T_OSP_REQ a,T_OSP_REQDETAIL b WHERE a.OSPREQID = b.OSPREQID AND b.OSPNO IN (SELECT OSPNP FROM T_BPM_OSP WHERE OSPNO IN ('OSP202302280002')) AND NVL(DATASTATUS, ' ')<>'撤销'
```
如果**DATASTATUS**为**NULL**,则返回**' '**,否则返回**DATASTATUS**
官方解释
The Oracle NVL () function allows you to **replace null** with a more meaningful alternative in the results of a query. The following shows the syntax of the NVL () function: The NVL () function accepts two arguments. If e1 evaluates to null, then NVL () function returns e2. If e1 evaluates to non-null, the NVL () function returns e1.
Oracle NVL()函数允许您在查询结果中用更有意义的替代项替换NULL。下面显示了NVL()函数的语法NVL()函数接受两个参数。如果e1的计算结果为空则NVL()函数返回e2。如果e1的计算结果为非空则nvl()函数返回e1。
### DECODE()
用法 DECODE(表达式, 条件1,返回值1,条件2,返回值2)
```sql
SELECT DECODE(AMOUNT, 0, NULL, AMOUNT) FROM T_PO_ORDERDETAIL;
```
如果**AMOUNT**等于**0**,则返回**NULL**,否则返回**AMOUNT**
```sql
SELECT DECODE(AMOUNT, 0, NULL, 1, 1, AMOUNT) FROM T_PO_ORDERDETAIL;
```
如果**AMOUNT**等于**0**,则返回**NULL**否则如果AMOUNT等于1则返回1否则返回**AMOUNT**
### DECODE替换NVL
在Oracle中DECODE函数通常可以替换使用NVL函数。DECODE函数可以在字段值满足多个条件时返回不同的结果值语法如下
```
DECODE(expr, search, result, default)
```
其中expr是要进行条件判断的表达式search是需要匹配的条件值result是匹配成功后返回的结果值default是在没有匹配成功时返回的默认值。
使用DECODE函数来替换NVL函数的示例如下
使用NVL函数处理NULL值
```
SELECT NVL(name, '未知') AS name FROM user;
```
使用DECODE函数替换NVL函数
```
SELECT DECODE(name, NULL, '未知', name) AS name FROM user;
```
以上语句中使用DECODE函数将name参数的NULL值替换为“未知”字符串。当name不为NULL时返回它本身的值。
## 特性
### Row Movement
ROW MOVEMENT特性最初是在8i时引入的其目的是提高分区表的灵活性——允许更新Partition Key。这一特性默认是关闭只是在使用到一些特殊功能时会要求打开。除了之前提到的更新Partition Key还有2个要求打开的ROW MOVEMENT的功能就是flushback table和Shrink Segment。
先看Flashback Table。这一功能能帮助我们及时回滚一些误操作防止数据意外丢失。在使用该功能之前必须先打开ROW MOVEMENT否则就会抛ORA-08189错误。我们看以下例子可以说明在使用Flashback Table功能时ROW MOVEMENT产生了什么作用
当开启ROW MOVEMENT后表被顺利的flashback了数据被找回。此时再比较flashback前后记录的ROWID大多数记录的物理位置都变化。这个过程的内部操作 可以通过对Flashback Table做SQL Trace来进一步观察。
通过Trace我们不难发现Flashback Table实际是通过Flashback Query将表中数据进行了一次删除、插入操作因此ROWID会发生变化。
在更新记录中的Partition Key时可能会导致该记录超出当前所在分区的范围需要将其转移到其他对应分区上因此要求开启ROW MOVEMENT。
这一操作产生影响的特殊之处在于这是个DML操作是和online transaction密切相关。对于这样一个UPDATE实际上分为3步先从原有分区将数据删除将原数据转移到新分区上更新数据。
其影响就在于以下几个方面:
- 一个UPDATE被分解为DELET、INSERT、UPDATE三个操作增加了性能负担。其中DELETE的查询条件与原UPDATE的查询条件相同新的UPDATE的查询条件是基于INSERT生成的新的ROWID
- 相应的Redo Log、Undo Log会增加
- 如果Update语句还涉及到了Local Index的字段的话新、旧2个分区上的Local Index都要被更新。
## 分区表
### 范围分区
```sql
create tablespace tetstbs1 datafile '/opt/oracle/oradata/ORCLCDB/tetstbs1.dbf' size 1m autoextend on next 5m maxsize unlimited;
create tablespace tetstbs2 datafile '/opt/oracle/oradata/ORCLCDB/tetstbs2.dbf' size 1m autoextend on next 5m maxsize unlimited;
create tablespace tetstbs3 datafile '/opt/oracle/oradata/ORCLCDB/tetstbs3.dbf' size 1m autoextend on next 5m maxsize unlimited;
-- 范围分区
create table pt_range_test1(
pid number(10),
pname varchar2(30)
) partition by range(pid)(
-- 分区 p1 pid值小于 1000 表空间 tetstbs1
partition p1 values less than(1000) tablespace tetstbs1,
-- 分区 p2 pid值小于 2000 表空间 tetstbs2
partition p2 values less than(2000) tablespace tetstbs2,
-- 分区 p3 pid值小于 number最大值 tetstbs3
partition p3 values less than(maxvalue) tablespace tetstbs3
) enable row movement;
insert into pt_range_test1 (pid, pname) values (1, '瑶瑶');
insert into pt_range_test1 (pid, pname) values (1500, '倩倩');
insert into pt_range_test1 (pid, pname) values (null, '优优');
commit;
select * from user_tab_partitions t;
select 'P1' 分区名, t.* from pt_range_test1 partition (p1) t union all
select 'P2' 分区名, t.* from pt_range_test1 partition (p2) t union all
select 'P3' 分区名, t.* from pt_range_test1 partition (p3) t;
select 'P1' 分区名, t.* from pt_range_test1 PARTITION (p1) t;
select t.* from pt_range_test1 PARTITION (p1) t;
select t.* FROM pt_range_test1 t;
```
### 列表分区
```sql
-- 列表分区
create table pt_list_test(
pid number(10),
pname varchar2(30),
sex varchar2(10)
) partition by list(sex)(
partition p1 values ('MAN', '男') tablespace tetstbs1,
partition p2 values ('WOMAN', '女') tablespace tetstbs2,
partition p3 values (default) tablespace tetstbs3
) enable row movement;
insert into pt_list_test (pid, pname, sex) values (1, '瑶瑶', '男');
insert into pt_list_test (pid, pname, sex) values (2, '倩倩', 'WOMAN');
insert into pt_list_test (pid, pname, sex) values (3, '优优', 'GOD');
insert into pt_list_test (pid, pname, sex) VALUES (4, '雨雨', '女');
insert into pt_list_test (pid, pname, sex) VALUES (5, '闫闫', 'MAN');
commit;
update pt_list_test set sex = '男' where pid = 1;
update pt_list_test set sex = '女' where pid = 1;
select 'p1' 分区名, t.*, rowid from pt_list_test PARTITION (p1) t UNION all
select 'p2' 分区名, t.*, rowid from pt_list_test PARTITION (p2) t UNION all
select 'p3' 分区名, t.*, rowid from pt_list_test PARTITION (p3) t;
```
### 哈希分区
```shell
create tablespace tetstbs4 datafile '/opt/oracle/oradata/ORCLCDB/tetstbs4.dbf' size 1m autoextend on next 5m maxsize unlimited;
-- 哈希分区
create table pt_hash_test(
pid number(10),
pname varchar2(30)
) partition by hash(pid)(
partition p1 tablespace tetstbs1,
partition p2 tablespace tetstbs2,
partition p3 tablespace tetstbs3,
partition p4 tablespace tetstbs4
);
-- 简写
create table pt_hash_test2(
pid number(10),
pname varchar2(30)
) partition by hash(pid)
partitions 4 store in (tetstbs1, tetstbs2, tetstbs3, tetstbs4);
insert into pt_hash_test (pid, pname) values (1, '瑶瑶');
insert into pt_hash_test (pid, pname) values (1500, '倩倩');
insert into pt_hash_test (pid, pname) values (null, '优优');
insert into pt_hash_test (pid, pname) values (2000, '闫闫');
commit;
select * from user_tab_partitions t;
select 'P1' 分区名, t.* from pt_hash_test partition (p1) t union all
select 'P2' 分区名, t.* from pt_hash_test partition (p2) t union all
select 'P3' 分区名, t.* from pt_hash_test partition (p3) t UNION all
SELECT 'p4' 分区名, t.* from pt_hash_test PARTITION (p4) t;
select 'P1' 分区名, t.* from pt_hash_test PARTITION (p1) t;
select t.* from pt_hash_test PARTITION (p1) t;
select t.* FROM pt_hash_test t;
```
### 组合分区
#### 范围列表
```sql
create table pt_range_list_test(
pid number(10),
pname varchar2(30),
sex varchar2(10),
create_date date
) partition by range(create_date)
subpartition by list(sex)(
partition p1 values less than(to_date('2020-01-01', 'YYYY-MM-DD')) tablespace tetstbs1(
subpartition sub1p1 values('MAN') tablespace tetstbs1,
subpartition sub2p1 values('WOMAN') tablespace tetstbs1,
subpartition sub3p1 values(default) tablespace tetstbs1
),
partition p2 values less than(to_date('2021-01-01', 'YYYY-MM-DD')) tablespace tetstbs2(
subpartition sub1p2 values('MAN') tablespace tetstbs2,
subpartition sub2p2 values('WOMAN') tablespace tetstbs2,
subpartition sub3p2 values(default) tablespace tetstbs2
),
partition p3 values less than(maxvalue) tablespace tetstbs3(
subpartition sub1p3 values('MAN') tablespace tetstbs3,
subpartition sub2p3 values('WOMAN') tablespace tetstbs3,
subpartition sub3p3 values(default) tablespace tetstbs3
)
) enable row movement;
insert into pt_range_list_test (pid, pname, sex, create_date) values(1, '瑶瑶', 'WOMAN', to_date('2019-02-02', 'YYYY-MM-DD'));
insert into pt_range_list_test (pid, pname, sex, create_date) values(2, '闫闫', 'MAN', to_date('2020-06-21', 'YYYY-MM-DD'));
insert into pt_range_list_test (pid, pname, sex, create_date) values(3, '雨雨', 'WOMAN', TO_DATE('2022-04-03', 'YYYY-MM-DD'));
commit;
delete from pt_range_list_test where pid = 1;
select 'p1' 分区名, t.* from pt_range_list_test PARTITION (p1) t UNION all
select 'p2' 分区名, t.* from pt_range_list_test PARTITION (p2) t UNION all
select 'p3' 分区名, t.* from pt_range_list_test PARTITION (p3) t;
```
### 自动分区
在Oracle Database 12.2 之前,如果使用列表分区,当插入的数据超过了分区列表值设定,则会抛出异常;而如果存在大量的列表值需要定义,则可能需要一一设置。
在12.2引入的新特性中 - Auto-List Partitioning 可以针对新的列表值,进行自动的分区创建,从而减少了维护的复杂性。
```sql
drop table enmotech purge;
CREATE TABLE enmotech (
PartID integer not null,
CretTm date not null,
PartCD varchar2(2) not null
) partition by list (partcd) automatic (
partition pBJ values ('BJ'),
partition pCD values ('CD'),
partition pGZ values ('GZ'),
partition pSH values ('SH')
);
```
如果这个自动分片的分区名不符合你的命名规则可以通过DDL语句去修改变更
```sql
alter table enmotech rename partition SYS_P290 to pKM;
```
对于已有的分区定义,可以通过关键字 automatic 和 manual 来进行分区定义的调整
```sql
alter table PEOPLE set partitioning automatic;
alter table PEOPLE set partitioning manual;
```
### 间隔分区