2012-10-31 106 views
0

我必須創建一個具有兩百個分區的範圍分區表。例如:使用大量的分區創建範圍分區表

CREATE TABLE emp (
    empno NUMBER(4), 
    ename VARCHAR2(30), 
    sal NUMBER 
) 
PARTITION BY RANGE(empno) (
partition e1 values less than (1000)  , 
partition e2 values less than (2000)  , 
... 
partition e200 values less than (MAXVALUE) 

);

有沒有一種方法可以指定範圍間隔,而不需要編寫兩百行來指定範圍?

+1

您正在使用哪個版本的Oracle?如果11g,那麼你應該真的去做間隔分區,這將爲你做所有的工作。只需要小心地對數據加以限制,這樣錯誤的大值不會導致Oracle創建不必要的分區。 –

回答

3
CREATE TABLE emp (
    empno NUMBER(4), 
    ename VARCHAR2(30), 
    sal NUMBER 
) 
PARTITION BY RANGE(empno) (
partition e1 values less than (1000)); 

begin 
    for k in 2..200 
    loop 
    execute immediate 
     'alter table emp add partition e'||k||' values less than ('||k*1000||')'; 
    end loop 
end; 

UPDATE:在11g存在的特徵來指定範圍分區和分區的間隔在插入到表將被創建。

但我不喜歡它,我不推薦它的原因有兩個:

1,您應該保持百達的第一個分區,因爲是參考。如果你試圖放棄它,你會得到SQL Error: ORA-14758: Last partition in the range section cannot be dropped;

2您無法控制分區名稱(AFAIK) 和間隔(這很醜陋)。如果錯誤地插入在未來的值某些分區將被跳過,你會發胖分區: (研究痘痘並沒有FAT分區添加到實例。)

Create table Z_TB_PART_TEST(
    id number 
) 
    partition by range(id) 
    interval(1000) 
(
    PARTITION PART_01 VALUES LESS THAN (1000) 
); 

INSERT INTO Z_TB_PART_TEST values (1500); 
INSERT INTO Z_TB_PART_TEST VALUES (10000); 
INSERT INTO Z_TB_PART_TEST VALUES (5000); 


    SELECT partition_name , high_value 
    FROM USER_TAB_PARTITIONS 
    WHERE table_name = 'Z_TB_PART_TEST'; 

    PART_01 1000 
    SYS_P141 2000 
    SYS_P142 11000 
    SYS_P143 6000 

UPDATE2:尼古拉斯克拉斯諾夫在評論中指出了一個解決方法:

那麼ORA-14758呢?它可以很容易地被避免: 我們暫時將我們的間隔分區錶轉換爲 分區表(alter table tb_table_test set interval()),刪除 分區,然後切換回區間分區表 (alter table tb_part_test set interval(1000))。

它的工作原理,我測試了它。但應該注意的是,所有分區都將凍結,它們將成爲範圍分區。如果你有空隙會留下(沒有分區將被添加到空隙中)。因此,參考分區將成爲更改爲interval之前的最後一個分區。這是錯誤說的:Last partition in the range section cannot be dropped

因此,您將有一段範圍分區和一段Interval分區及其所有優點。

+0

作爲一個簡要說明。爲了保留分區類型,我們可以截斷我們想要刪除的分區,然後將其與下一個分區合併。根據分區的大小,可能會有很多重做。 –

3

你沒有說你正在使用的是哪個版本的Oracle,但是如果它發生的是你的Oracle版本是11g,那麼CREATE TABLE語句的INTERVAL子句將允許你爲表建立間隔分區。以下是一個示例:

SQL> Create table TB_PART_TEST(
    2 id number 
    3 ) 
    4 partition by range(id) 
    5 interval(1000) 
    6 (
    7 partition Part_01 values less than (1000) 
    8 ); 

table created 

SQL> select partition_name 
    2  , high_value 
    3 from user_tab_partitions 
    4 where table_name = 'TB_PART_TEST'; 



PARTITION_NAME HIGH_VALUE 
------------------------------ 
    PART_01   1000 


    SQL> insert into TB_PART_TEST(id) 
    2 values(1500); 

    1 row created 

    SQL> commit; 

    commit complete 

    SQL> select partition_name 
    2  , high_value 
    3 from user_tab_partitions 
    4 where table_name = 'TB_PART_TEST'; 

    PARTITION_NAME HIGH_VALUE 
------------------------------ 
    PART_01   1000 
    SYS_P63   2000 
+1

我正要回答同樣的問題!如果使用11g,這絕對是一種方法。還可以查看Tim Hall關於分區的出色總結,其中包括有關間隔分區的信息:http://www.oracle-base。com/articles/11g/partitioning-enhancements-11gr1.php#interval_partitioning –

+0

我使用的是oracle 10g ...我有這個11g的方法,但不能在生產機器上使用它.. – subodh1989

+0

我知道這個功能,但我不喜歡它(或沒有充分測試它)。有兩個原因。我會稍後更新我的答案。 –