暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 分区表的FOR语句

指定一个分区除了使用分区名称外,很多时候还可以使用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> 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: 分区编号无效或超出范围
复制

完全仿照USER_TAB_PARTITIONS视图中的分区定义,错误依旧。

最终发现了问题所在,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
复制
最后修改时间:2020-02-07 14:47:20
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论