2013-09-17 2 views
4

Я хотел бы перейти от Range Partition к Range-Interval, но моя текущая таблица имеет раздел на MAXVALUE и столбец, используемый для разделения позволяет нулевые значения :(От Range Partition к Range-Interval

Например: Say мы имеем:

create table a (b number) 
partition by range (b) (
    PARTITION p0 VALUES LESS THAN (10), 
    PARTITION p1 VALUES LESS THAN (50), 
    PARTITION p2 VALUES LESS THAN (MAXVALUE) 
); 

Тогда мы заселить:

INSERT INTO a(b) VALUES (1); 
INSERT INTO a(b) VALUES (11); 
INSERT INTO a(b) VALUES (51); 
INSERT INTO a(b) VALUES (null); 

чтобы иметь возможность перейти на интервале, необходимо удалить раздел с MAXVALUE, поэтому другие значения должны быть перенесены в новый раздел.
51 не проблема, я бы создал раздел, где с VALUES LESS than 100, но как насчет NULL?

Я думал о переходе на что-то вроде раздела по диапазону (NVL(b,0)), но я боюсь, что придется перерабатывать всю таблицу (возможно, в реальной таблице много данных).

Любая идея?

ответ

6

You can't have NULL in the partition key column of an interval partitioned table (как 12.1):

Ограничения на интервального секционирования

  • Вы можете указать только один секционирования ключевой столбец, и он должен быть номер, дата, FLOAT или TIMESTAMP.

[...]

  • Вы не можете указать NULL значения для столбца ключа секционирования.

Вы не можете использовать выражения для ключа разделения. Однако, как было предложено @Shoelace вы можете использовать виртуальный столбец (содержащий ваше выражение) в колонке раздела:

SQL> CREATE TABLE a (b NUMBER, comput_b NUMBER AS (NVL(b, 0))) 
    2 PARTITION BY RANGE (comput_b) (
    3 PARTITION p0 VALUES LESS THAN (0), 
    4 PARTITION p1 VALUES LESS THAN (50), 
    5 PARTITION p2 VALUES LESS THAN (MAXVALUE) 
    6 ); 

Table created 

SQL> INSERT INTO a(b) VALUES (1); 
1 row inserted 
SQL> INSERT INTO a(b) VALUES (11); 
1 row inserted 
SQL> INSERT INTO a(b) VALUES (51); 
1 row inserted 
SQL> INSERT INTO a(b) VALUES (null); 
1 row inserted 

SQL> SELECT * FROM a; 

     B COMPUT_B 
---------- ---------- 
     1   1 
     11   11 
        0 
     51   51 

В данном конкретном случае, я думаю, вам нужно будет восстановить таблицу.

+1

Это не совсем так. так как по крайней мере 11g вы можете создать виртуальный столбец (который является просто выражением) и использовать его для разделения ... – ShoeLace

+0

@ShoeLace Спасибо, я этого не знал! –

0

http://www.dba-oracle.com/t_interval_partitioning.htm говорит, что вы можете изменить диапазон интервала и обратно с помощью alter table синтаксиса

т.е.

alter table a set INTERVAL(100) ; 

полный альтер синтаксис таблицы для 11g доступна here.

К сожалению, это, похоже, не позволяет вам изменять столбцы разделов .. так что я думаю, что вам не повезло. но вы всегда можете попробовать.