2013-06-26 45 views
3

這是一個問題的兩個部分:的Oracle SQL:選擇數據和表分區的名稱和截斷分區

1)是否有可能檢索數據存在於使用SELECT語句,基於分區的名稱它的ROWID或其他標識符?

例如。

SELECT DATA_ID, CATEGORY, VALUE, **PARTITION_NAME** 
FROM MYTABLE 
WHERE CATEGORY = 'ABC' 

2)是否有可能截斷表的單個分區,而不刪除存儲在其他分區中的數據?

我有一個超過10億行的表,按分類劃分哈希。只有少數類別的數據存在問題,因此重新創建整個表格是沒有意義的,但即使所有約束都處於非活動狀態,從表格中刪除數據也需要很長時間。

+0

你是什麼「的問題與他們的數據」是什麼意思? – APC

+0

@APC:我的意思是說有些數據不正確/過時,需要更換。 – woemler

+0

也許你可以將一個受影響的分區交換到一個表中,修復或重新創建數據,然後將其交換回來? (http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_3001.htm#i2131250) –

回答

5

感謝您對rowid的暗示,我找到了一個解決方案。如果你有rowid,應該可以確定該行所屬的對象。

一個最小的例如,具有4 hash分區:

CREATE TABLE pt (i NUMBER) 
PARTITION BY HASH (i) (PARTITION pt1, PARTITION pt2, PARTITION pt3, PARTITION pt4); 

INSERT INTO pt SELECT ROWNUM FROM all_objects WHERE ROWNUM < 20; 

現在,每行具有ROWID。您可以通過DBMS_ROWID.ROWID_OBJECT找到對象編號。該字典表USER_OBJECTS有那麼OBJECT_NAME(=表名)和subobject_name(=分區的名稱):

SELECT i, 
     ROWID AS row_id, 
     dbms_rowid.rowid_object(ROWID) AS object_no, 
     (SELECT subobject_name 
      FROM user_objects 
     WHERE object_id = dbms_rowid.rowid_object(pt.ROWID)) AS partition_name 
    FROM pt 
ORDER BY 3; 

I ROW_ID    OBJECT_NO PARTITION_NAME 
6 AAALrYAAEAAAATRAAA 47832 PT1 
11 AAALrYAAEAAAATRAAB 47832 PT1 
13 AAALrYAAEAAAATRAAC 47832 PT1 
9 AAALrZAAEAAAATZAAA 47833 PT2 
10 AAALrZAAEAAAATZAAB 47833 PT2 
12 AAALrZAAEAAAATZAAC 47833 PT2 
17 AAALrZAAEAAAATZAAD 47833 PT2 
19 AAALrZAAEAAAATZAAE 47833 PT2 
2 AAALraAAEAAAAThAAA 47834 PT3 
5 AAALraAAEAAAAThAAB 47834 PT3 
18 AAALraAAEAAAAThAAD 47834 PT3 
8 AAALraAAEAAAAThAAC 47834 PT3 
1 AAALrbAAEAAAATpAAA 47835 PT4 
3 AAALrbAAEAAAATpAAB 47835 PT4 
4 AAALrbAAEAAAATpAAC 47835 PT4 
7 AAALrbAAEAAAATpAAD 47835 PT4 
+0

+1很好的答案!這絕對符合我的問題第一部分的法案! – woemler

+0

謝謝!我只是用它來探索周圍。要截斷或更改分區,我會使用@jonearls的'PARTITION FOR'語法回答... –

3

1)no。你不能這樣做,你將不得不查詢all_tab_partitions找出一個ceratain值的分區。

2)alter table x truncate partition y

+0

您能澄清我將如何使用'all_tab_partitions'表來找出某個特定數據行的哪個分區屬於? – woemler

+0

取決於你正在使用的分區的類型(我猜測範圍)。每個分區的高值在'high_value'列中,所以如果它是一個範圍分區,你需要最後一個分區,而你的值小於'high_value'。閱讀[docs here](http://docs.oracle.com/cd/B28359_01/server.111/b28320/statviews_2096.htm) – haki

+0

有問題的表是按類別進行散列分區的,所以'high_value'列爲空。 – woemler

2

與其尋找分區名,在PARTITION FOR語法使用的值:

ALTER TABLE MYTABLE TRUNCATE PARTITION FOR ('ABC'); 

儘管這種操作不會影響其他分區中的數據可能會讓你的索引UNUSABLE 。重建相關索引或在DDL中使用UPDATE INDEXES

+0

你能在這裏解釋一下這個語法嗎?我假設ABC''是'CATEGORY'的值,就像在我的例子中一樣,但是這個語句怎麼知道''ABC''是指'CATEGORY'列? – woemler

+1

這是分區鍵,換句話說就是用於分區表的列(或列)。 –