Oracle 分区表的 FOR 语句,你这样用过吗?
在11g以后,Oracle简化了指定分区的方式,不再需要明确指定分区名称,而是可以通过指定分区键值列数据的方式来指向对应的分区。
指定一个分区除了使用分区名称外,很多时候还可以使用FOR语句。
从11g开始,对分区进行操作的时候,不仅可以使用分区名称,还可以使用FOR语句。
在10g中,MERGE RANGE分区的语句如下:
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Solaris: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
SQL> CREATE TABLE T_PART_RANGE2 (ID NUMBER, 3 NAME VARCHAR2(30), 4 CREATE_DATE DATE)5 PARTITION BY RANGE (CREATE_DATE) 6 (PARTITION P1 VALUES LESS THAN (TO_DATE('2009-1', 'YYYY-MM')),7 PARTITION P2 VALUES LESS THAN (TO_DATE('2009-4', 'YYYY-MM')),8 PARTITION P3 VALUES LESS THAN (TO_DATE('2009-7', 'YYYY-MM')));表已创建。SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
SQL> ALTER TABLE T_PART_RANGE 2 MERGE PARTITIONS P2, P33 INTO PARTITION P3;表已更改。
而在11g中,除了使用分区名称外,还可以使用FOR语句来代替,比如:
SQL> SELECT * FROM V$VERSION;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SQL> CREATE TABLE T_PART_RANGE2 (ID NUMBER, 3 NAME VARCHAR2(30), 4 CREATE_DATE DATE)5 PARTITION BY RANGE (CREATE_DATE) 6 (PARTITION P1 VALUES LESS THAN (TO_DATE('2009-1', 'YYYY-MM')),7 PARTITION P2 VALUES LESS THAN (TO_DATE('2009-4', 'YYYY-MM')),8 PARTITION P3 VALUES LESS THAN (TO_DATE('2009-7', 'YYYY-MM')));表已创建。SQL> ALTER TABLE T_PART_RANGE2 MERGE PARTITIONS3 FOR(TO_DATE('2009-01', 'YYYY-MM')), 4 FOR(TO_DATE('2009-04', 'YYYY-MM'))5 INTO PARTITION P3;表已更改。
这种语法的优势对于范围分区还不是很明显,而对于INTERVAL分区就十分有意义了。由于INTERVAL分区的分区名称是系统产生的,用户对INTERVAL分区最直观的莫过于存在分区中的数据的范围,根据分区的定义和INTERVAL的设置很容易可以确定分区的范围和其中的数据,但是分区的名称就必须通过数据字典才能查询得到。
一个INTERVAL分区的简单的例子:
SQL> CREATE TABLE T_PART_INTER2 (ID NUMBER, 3 NAME VARCHAR2(30), 4 CREATE_DATE DATE)5 PARTITION BY RANGE (CREATE_DATE) 6 INTERVAL (INTERVAL '3' MONTH)7 (PARTITION P1 VALUES LESS THAN (TO_DATE('2009-1', 'YYYY-MM')),8 PARTITION P2 VALUES LESS THAN (TO_DATE('2009-4', 'YYYY-MM')));表已创建。SQL> INSERT INTO T_PART_INTER2 SELECT ROWNUM, OBJECT_NAME, SYSDATE - ROWNUM * 103 FROM USER_OBJECTS;已创建9行。
SQL> COMMIT;提交完成。SQL> ALTER TABLE T_PART_INTER2 MERGE PARTITIONS3 FOR(TO_DATE('2009-10', 'YYYY-MM')),4 FOR(TO_DATE('2010-1', 'YYYY-MM'));表已更改。
继续上面的例子:
SQL> CREATE TABLE T_PART_RANGE2 (ID NUMBER,3 NAME VARCHAR2(30),4 CREATE_DATE DATE)5 PARTITION BY RANGE (CREATE_DATE)6 (PARTITION P1 VALUES LESS THAN (TO_DATE('2009-1', 'YYYY-MM')),7 PARTITION P2 VALUES LESS THAN (TO_DATE('2009-4', 'YYYY-MM')),8 PARTITION P3 VALUES LESS THAN (TO_DATE('2009-7', 'YYYY-MM')));表已创建。
下面打算通过FOR语句的方式合并P2和P3分区:
SQL> ALTER TABLE T_PART_RANGE2 MERGE PARTITIONS3 FOR(TO_DATE('2009-4', 'YYYY-MM')),4 FOR(TO_DATE('2009-7', 'YYYY-MM'))5 INTO PARTITION P3;
ALTER TABLE T_PART_RANGE*第 1 行出现错误:ORA-14702: 分区编号无效或超出范围
语句出现了ORA-14702错误,查询Oracle的错误文档:
ORA-14702: The partition number is invalid or out-of-range
Cause: Attempted to use nonnumerical value or the number was out of range of the partitions.
Action: Use a valid partition number.
根据错误文档的描述,感觉是分区键值指定出现了错误,查询分区信息:
SQL> SELECT PARTITION_NAME, HIGH_VALUE2 FROM USER_TAB_PARTITIONS3 WHERE TABLE_NAME = 'T_PART_RANGE'4 ORDER BY 1;
PARTITION_NAME HIGH_VALUE
-------------- ----------------------------------------------------------------------------------
P1 TO_DATE(' 2009-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
P2 TO_DATE(' 2009-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
P3 TO_DATE(' 2009-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
难道是分区键值指定有问题:
SQL> ALTER TABLE T_PART_RANGE2 MERGE PARTITIONS3 FOR(TO_DATE(' 2009-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),4 FOR(TO_DATE(' 2009-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))5 INTO PARTITION P3;
ALTER TABLE T_PART_RANGE*第 1 行出现错误:ORA-14702: 分区编号无效或超出范围完全仿照USER_TAB_PARTITIONS视图中的分区定义,错误依旧。
最终发现了问题所在,FOR语句中指定的并不是分区定义时使用的值,而是存储在当前分区中的值:
SQL> ALTER TABLE T_PART_RANGE2 MERGE PARTITIONS3 FOR(TO_DATE('2009-1', 'YYYY-MM')),4 FOR(TO_DATE('2009-4', 'YYYY-MM'));表已更改。SQL> SELECT PARTITION_NAME, HIGH_VALUE2 FROM USER_TAB_PARTITIONS3 WHERE TABLE_NAME = 'T_PART_RANGE'4 ORDER BY 1;
PARTITION_NAME HIGH_VALUE
--------------- ---------------------------------------------------------------------------------
P1 TO_DATE(' 2009-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS_P78 TO_DATE(' 2009-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')可以看到,在使用FOR语句的时候,是根据P1和P2分区定义时的日期指定的分区,但是MERGE的结果却是P2和P3分区进行了合并。
因此Oracle并非根据分区定义来判断分区,而是根据用户给出的值,来判断所属分区,所以,P1分区和SYS_P78分区的合并完全可以写成:
SQL> ALTER TABLE T_PART_RANGE2 MERGE PARTITIONS3 FOR(TO_DATE('1970-1', 'YYYY-MM')),4 FOR(TO_DATE('2009-5', 'YYYY-MM'));表已更改。
由于FOR语句的这种特性,使得HASH分区也可以使用这个特性:
SQL> CREATE TABLE T_PART_HASH2 (ID NUMBER,3 NAME VARCHAR2(30))4 PARTITION BY HASH(ID)5 PARTITIONS 16;表已创建。SQL> ALTER TABLE T_PART_HASH2 MOVE PARTITION FOR(6);表已更改。
这个例子对包含ID为6的分区进行了MOVE操作,而且甚至不需要指定的ID存在。
最后给一个简单的LIST分区的SPLIT的例子:
SQL> CREATE TABLE T_PART_LIST2 (3 OWNER VARCHAR2(30),4 TABLE_NAME VARCHAR2(30),5 TABLESPACE_NAME VARCHAR2(30),6 STATUS VARCHAR2(18)7 )8 PARTITION BY LIST (TABLESPACE_NAME)9 (10 PARTITION P1 VALUES ('SYSTEM'),11 PARTITION P2 VALUES ('YANGTK'),12 PARTITION P3 VALUES (DEFAULT)13 );表已创建。SQL> ALTER TABLE T_PART_LIST2 SPLIT PARTITION FOR('SYSAUX')3 VALUES ('SYSAUX')4 INTO (PARTITION P3, PARTITION P4);表已更改。SQL> SELECT PARTITION_NAME, HIGH_VALUE2 FROM USER_TAB_PARTITIONS3 WHERE TABLE_NAME = 'T_PART_LIST'4 ORDER BY 1;
PARTITION_NAME HIGH_VALUE
--------------- -------------------------------------
P1 'SYSTEM'
P2 'YANGTK'
P3 'SYSAUX'
P4 DEFAULT出处:https://www.modb.pro/db/15418
点击下图查看更多 ↓
云和恩墨大讲堂 | 一个分享交流的地方
长按,识别二维码,加入万人交流社群
请备注:云和恩墨大讲堂
点个“在看”
你的喜欢会被看到????
Oracle 分区表的 FOR 语句,你这样用过吗?相关推荐
- oracle分区表带入SQL语句,Oracle 分区表常用SQL语句 (转载)
********* 为分区表建立一个单独的表空间 *********/create tablespace ts_partition datafile '/home/oracle/oradata/esa ...
- oracle更改分区表结构,Oracle分区修改的语句
Oracle分区修改的语句 1.增加一个分区 ALTER TABLE sales ADD PARTITION jan96 VALUES LESS THAN ( '01-FEB-1999' ) TABL ...
- 导入导出 Oracle 分区表数据
--**************************** -- 导入导出 Oracle 分区表数据 --**************************** 导入导入Oracle 分区表数据是 ...
- oracle分区表编程,Oracle分区表详解
当前位置:我的异常网» 编程 » Oracle分区表详解 Oracle分区表详解 www.myexceptions.net 网友分享于:2013-10-28 浏览:25次 Oracle分区表详解 ...
- 分区表需要数据备份吗oracle,Oracle 分区表数据的导入与导出(1)
--**************************** -- 导入导出 Oracle 分区表数据 --**************************** 导入导入Oracle 分区表数据是 ...
- 03 Oracle分区表
Oracle分区表 先说句题外话- 欢迎成都天府软件园的小伙伴来面基交流经验~ 一:什么是分区(Partition)? 分区是将一个表或索引物理地分解为多个更小.更可管理的部分. 分区对应用透明, ...
- 深入学习Oracle分区表及分区索引
关于分区表和分区索引(About Partitioned Tables and Indexes)对于10gR2而言,基本上可以分成几类: ? Range(范围)分区 ? Has ...
- java oracle 分区查询_深入学习Oracle分区表及分区索引
深入学习Oracle分区表及分区索引 关于分区表和分区索引(About Partitioned Tables and Indexes)对于10gR2而言,基本上可以分成几类: • Rang ...
- Oracle分区表之创建维护分区表索引的详细步骤
墨墨导读:本文来自墨天轮用户投稿,详细描述Oracle分区表之创建维护分区表索引的步骤. 分区索引分为本地(local index)索引和全局索引(global index).局部索引比全局索引容易管 ...
最新文章
- 剑指 Offer 06. 从尾到头打印链表(递归、逆置链表、头部动态插入)
- 设计模式--模板方法模式--Java实现-- java访问控制关键字用法
- php carbon,laravel Carbon函数
- spring security3.x学习(3)_初探过滤器机制和auto-config用法
- 数据结构(二):线性表的使用原则以及链表的应用-稀疏矩阵的三元组表示
- Raki的读paper小记:How to Fine-Tune BERT for Text Classification?
- C# Winform开发教程
- 在校大学生关于程序员培训机构的想法
- PCB板层简介+走线
- 农产品追溯管理平台解决方案
- elang mnesia 数据库操作
- Linux下利用nc命令来监控检测服务器的端口使用情况
- 排序算法(希尔排序)
- layUIselect下拉菜单
- 最详细JMX远程连接服务器Zookeeper失败问题踩坑和总结
- 基于FPGA的SNR噪声分析
- 007-安装百度云,搜狗输入法,播放器
- arm汇编指令详细整理及实例详解
- 【2020/02/11】每日早报
- 2021年安全员-A证考试报名及安全员-A证实操考试视频