百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Oracle 分区表的 FOR 语句,你这样用过吗?

mhr18 2024-09-14 05:37 36 浏览 0 评论

作者:杨廷琨

原文链接:https://www.modb.pro/db/15418


在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_RANGE
  2  (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, P3
  3  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_RANGE
  2  (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_RANGE
  2  MERGE PARTITIONS
  3  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_INTER
  2  (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_INTER
  2  SELECT ROWNUM, OBJECT_NAME, SYSDATE - ROWNUM * 10
  3  FROM USER_OBJECTS;已创建9行。SQL> COMMIT;提交完成。SQL> ALTER TABLE T_PART_INTER
  2  MERGE PARTITIONS
  3  FOR(TO_DATE('2009-10', 'YYYY-MM')),
  4  FOR(TO_DATE('2010-1', 'YYYY-MM'));表已更改。


继续上面的例子:

SQL> CREATE TABLE T_PART_RANGE
  2  (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_RANGE
  2  MERGE PARTITIONS
  3  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_VALUE
  2  FROM USER_TAB_PARTITIONS
  3  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_RANGE
  2  MERGE PARTITIONS
  3  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: 分区编号无效或超出范围


最终发现了问题所在,FOR语句中指定的并不是分区定义时使用的值,而是存储在当前分区中的值:

SQL> ALTER TABLE T_PART_RANGE
  2  MERGE PARTITIONS
  3  FOR(TO_DATE('2009-1', 'YYYY-MM')),
  4  FOR(TO_DATE('2009-4', 'YYYY-MM'));表已更改。SQL> SELECT PARTITION_NAME, HIGH_VALUE
  2  FROM USER_TAB_PARTITIONS
  3  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_RANGE
  2  MERGE PARTITIONS
  3  FOR(TO_DATE('1970-1', 'YYYY-MM')),
  4  FOR(TO_DATE('2009-5', 'YYYY-MM'));表已更改。


由于FOR语句的这种特性,使得HASH分区也可以使用这个特性:

SQL> CREATE TABLE T_PART_HASH
  2  (ID NUMBER,
  3  NAME VARCHAR2(30))
  4  PARTITION BY HASH(ID)
  5  PARTITIONS 16;表已创建。SQL> ALTER TABLE T_PART_HASH
  2  MOVE PARTITION FOR(6);表已更改。


这个例子对包含ID为6的分区进行了MOVE操作,而且甚至不需要指定的ID存在。

最后给一个简单的LIST分区的SPLIT的例子:

SQL> CREATE TABLE T_PART_LIST
  2  (
  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_LIST
  2  SPLIT PARTITION FOR('SYSAUX')
  3  VALUES ('SYSAUX')
  4  INTO (PARTITION P3, PARTITION P4);表已更改。SQL> SELECT PARTITION_NAME, HIGH_VALUE
  2  FROM USER_TAB_PARTITIONS
  3  WHERE TABLE_NAME = 'T_PART_LIST'
  4  ORDER BY 1;
PARTITION_NAME  HIGH_VALUE
--------------- -------------------------------------
P1              'SYSTEM'
P2              'YANGTK'
P3              'SYSAUX'
P4              DEFAULT


想了解更多关于数据库、云技术的内容吗?

快来关注“数据和云"、"云和恩墨,"公众号及"云和恩墨"官方网站,我们期待大家一同学习与进步!

小程序”DBASK“在线问答,随时解惑,欢迎了解和关注!

相关推荐

【预警通报】关于WebLogic存在远程代码执行高危漏洞的预警通报

近日,Oracle官方发布了2021年1月关键补丁更新公告CPU(CriticalPatchUpdate),共修复了包括CVE-2021-2109(WeblogicServer远程代码执行漏洞)...

医院信息系统突发应急演练记录(医院信息化应急演练)

信息系统突发事件应急预案演练记录演练内容信息系统突发事件应急预案演练参与人员信息科参与科室:全院各部门日期xxxx-xx-xx时间20:00至24:00地点信息科记录:xxx1、...

一文掌握怎么利用Shell+Python实现完美版的多数据源备份程序

简介:在当今数字化时代,无论是企业还是个人,数据的安全性和业务的连续性都是至关重要的。数据一旦丢失,可能会造成无法估量的损失。因此,如何有效地对分布在不同位置的数据进行备份,尤其是异地备份,成为了一个...

docker搭建系统环境(docker搭建centos)

Docker安装(CentOS7)1.卸载旧版Docker#检查已安装版本yumlistinstalled|grepdocker#卸载旧版本yumremove-ydocker.x...

基础篇:数据库 SQL 入门教程(sql数据库入门书籍推荐)

SQL介绍什么是SQLSQL指结构化查询语言,是用于访问和处理数据库的标准的计算机语言。它使我们有能力访问数据库,可与多种数据库程序协同工作,如MSAccess、DB2、Informix、M...

Java21杀手级新特性!3行代码性能翻倍

导语某券商系统用这招,交易延迟从12ms降到0.8ms!本文揭秘Oracle官方未公开的Record模式匹配+虚拟线程深度优化+向量API神操作,代码量直降70%!一、Record模式匹配(代码量↓8...

一文读懂JDK21的虚拟线程(java虚拟线程)

概述JDK21已于2023年9月19日发布,作为Oracle标准Java实现的一个LTS版本发布,发布了15想新特性,其中虚拟线程呼声较高。虚拟线程是JDK21中引入的一项重要特性,它是一种轻量级的...

效率!MacOS下超级好用的Linux虚拟工具:Lima

对于MacOS用户来说,搭建Linux虚拟环境一直是件让人头疼的事。无论是VirtualBox还是商业的VMware,都显得过于笨重且配置复杂。今天,我们要介绍一个轻巧方便的纯命令行Linux虚拟工具...

所谓SaaS(所谓三维目标一般都应包括)

2010年前后,一个科技媒体的主编写一些关于云计算的概念性问题,就可以作为头版头条了。那时候的云计算,更多的还停留在一些概念性的问题上。而基于云计算而生的SaaS更是“养在深闺人未识”,一度成为被IT...

ORA-00600 「25027」 「x」报错(报错0xc0000001)

问题现象:在用到LOB大对象的业务中,进行数据的插入,失败了,在报警文件中报错:ORA-00600:内部错误代码,参数:[25027],[10],[0],[],[],[],[],[...

安卓7源码编译(安卓源码编译环境lunch失败,uname命令找不到)

前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...

编译安卓源码(编译安卓源码 电脑配置)

前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...

360 Vulcan Team首战告捷 以17.5万美金强势领跑2019“天府杯“

2019年11月16日,由360集团、百度、腾讯、阿里巴巴、清华大学与中科院等多家企业和研究机构在成都联合主办了2019“天府杯”国际网络安全大赛暨2019天府国际网络安全高峰论坛。而开幕当日最激荡人...

Syslog 日志分析与异常检测技巧(syslog发送日志配置)

系统日志包含有助于分析网络设备整体运行状况的重要信息。然而,理解并从中提取有效数据往往颇具挑战。本文将详解从基础命令行工具到专业日志管理软件的全流程分析技巧,助你高效挖掘Syslog日志价值。Gr...

从Oracle演进看数据库技术的发展(从oracle演进看数据库技术的发展的过程)

数据库技术发展本质上是应用需求驱动与基础架构演进的双向奔赴,如何分析其技术发展的脉络和方向?考虑到oracle数据库仍然是这个领域的王者,以其为例,管中窥豹,对其从Oracle8i到23ai版本的核...

取消回复欢迎 发表评论: