2013-06-26 44 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

这是分区键,换句话说就是用于分区表的列(或列)。 –