2012-09-11 48 views
6

Tôi đang sử dụng một bảng oracle 11 với khoảng phân vùng và danh sách subpartitioning như thế này (giản thể):Oracle: làm thế nào để thả một subpartition của một phân vùng cụ thể

CREATE TABLE LOG 
(
    ID NUMBER(15, 0) NOT NULL PRIMARY KEY 
, MSG_TIME DATE NOT NULL 
, MSG_NR VARCHAR2(16 BYTE) 
) PARTITION BY RANGE (MSG_TIME) INTERVAL (NUMTOYMINTERVAL (1,'MONTH')) 
    SUBPARTITION BY LIST (MSG_NR) 
    SUBPARTITION TEMPLATE (
    SUBPARTITION login VALUES ('FOO') 
    , SUBPARTITION others VALUES (DEFAULT) 
    ) 
    (PARTITION oldvalues VALUES LESS THAN (TO_DATE('01-01-2010','DD-MM-YYYY'))); 

Làm thế nào để thả một subpartitition cụ thể cho một cụ thể tháng mà không biết tên (hệ thống được tạo) của phân mục con? Có một cú pháp "alter table ... drop subpartition for (subpartition_key_value , ...)" nhưng tôi không thấy cách chỉ định tháng mà tôi đang xóa phân mục phụ. partition administration guide cũng không đưa ra bất kỳ ví dụ nào. 8-}

Trả lời

3

Khi nó quay ra, các "subpartition cho" cú pháp không thực sự làm việc, mặc dù điều đó có vẻ là một Oracle bí mật không muốn để kể cho bạn nghe. :-)

ALTER TABLE TB_LOG_MESSAGE DROP SUBPARTITION FOR 
     (TO_DATE('01.02.2010','DD.MM.YYYY'), 'FOO') 

này sẽ xoá subpartition rằng sẽ chứa MSG_TIME 2010/02/01 và MSG_NR FOO. (Không cần thiết phải có một hàng thực tế với chính xác MSG_TIME và MSG_NR này. Nó sẽ đưa ra một lỗi nếu không có phân vùng phụ như vậy.)

+3

Nếu bạn google cho "bỏ phân mục con", bạn thực sự tìm thấy đơn đăng ký sáng chế bao gồm cú pháp đó. 8- {} Bằng sáng chế phần mềm có thể trở nên xấu xa hơn không? http://www.patentstorm.us/applications/20080313133/description.html –

+0

Nó đã được xuất bản vào năm 2013 http://www.google.com.vn/patents/US8356014 (liên kết mới vì tôi không thể thấy bất kỳ điều gì trong liên kết của hstoerr) – jmsu

3

Bạn có thể sử dụng các bảng siêu dữ liệu để có được tên subpartition cụ thể:

SQL> insert into log values (1, sysdate, 'FOO'); 

1 row(s) inserted. 

SQL> SELECT p.partition_name, s.subpartition_name, p.high_value, s.high_value 
    2 FROM user_tab_partitions p 
    3   JOIN 
    4   user_tab_subpartitions s 
    5   ON s.table_name = p.table_name 
    6  AND s.partition_name = p.partition_name 
    7  AND p.table_name = 'LOG'; 

PARTITION_NAME SUBPARTITION_NAME HIGH_VALUE HIGH_VALUE 
--------------- ------------------ ------------ ---------- 
OLDVALUES  OLDVALUES_OTHERS 2010-01-01 DEFAULT 
OLDVALUES  OLDVALUES_LOGIN 2010-01-01 'FOO' 
SYS_P469754  SYS_SUBP469753  2012-10-01 DEFAULT 
SYS_P469754  SYS_SUBP469752  2012-10-01 'FOO' 

SQL> alter table log drop subpartition SYS_SUBP469752; 

Table altered. 

Nếu bạn muốn thả một phân vùng tự động, nó có thể được khó khăn để tìm thấy nó với quan điểm ALL_TAB_SUBPARTITIONSHIGH_VALUE cột có thể không đơn giản để truy vấn. Trong trường hợp đó bạn có thể sử dụng DBMS_ROWID để tìm subpartition object_id của một hàng đưa ra:

SQL> insert into log values (4, sysdate, 'FOO'); 

1 row(s) inserted. 

SQL> DECLARE 
    2  l_rowid_in   ROWID; 
    3  l_rowid_type  NUMBER; 
    4  l_object_number NUMBER; 
    5  l_relative_fno  NUMBER; 
    6  l_block_number  NUMBER; 
    7  l_row_number  NUMBER; 
    8 BEGIN 
    9  SELECT rowid INTO l_rowid_in FROM log WHERE id = 4; 
10  dbms_rowid.rowid_info(rowid_in  =>l_rowid_in  , 
11       rowid_type  =>l_rowid_type , 
12       object_number =>l_object_number, 
13       relative_fno =>l_relative_fno , 
14       block_number =>l_block_number , 
15       row_number  =>l_row_number ); 
16  dbms_output.put_line('object_number ='||l_object_number); 
17 END; 
18/

object_number =15838049 

SQL> select object_name, subobject_name, object_type 
    2 from all_objects where object_id = '15838049'; 

OBJECT_NAME  SUBOBJECT_NAME OBJECT_TYPE 
--------------- --------------- ------------------ 
LOG    SYS_SUBP469757 TABLE SUBPARTITION 
1

Cảm ơn bài đăng - rất hữu ích cho tôi.

Một quan sát mặc dù trên kịch bản ở trên để xác định phân vùng và xóa nó:

Các object_id trả về bởi dbms_rowid.rowid_info không phải là object_id của bảng all_objects. Nó thực sự là data_object_id. Nó được quan sát thấy rằng các id này thường phù hợp. Tuy nhiên, sau khi cắt bớt bảng được phân đoạn nhiều lần, các id này được phân tách trong cơ sở dữ liệu của tôi. Do đó nó có thể là hợp lý để thay vì sử dụng các data_object_id để tìm ra tên của phân vùng:

select object_name, subobject_name, object_type 
from all_objects where data_object_id = '15838049'; 

From the table description of ALL_OBJECTS: 

object_id số đối tượng của đối tượng DATA_OBJECT_ID số đối tượng của phân khúc, trong đó có đối tượng

http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_rowid.htm

Trong mã mẫu được cung cấp trong liên kết ở trên, DBMS_ROWID.ROWID_OBJECT(row_id) được sử dụng để lấy cùng thông tin được cung cấp bởi dbms_rowid.rowid_info. Tuy nhiên, tài liệu xung quanh mẫu này đề cập rằng nó là một số đối tượng dữ liệu từ ROWID.

Ví dụ

Ví dụ này trả về ROWID cho một hàng trong bảng EMP, chiết xuất số đối tượng dữ liệu từ các ROWID, sử dụng chức năng ROWID_OBJECT trong gói DBMS_ROWID, sau đó hiển thị số đối tượng:

DECLARE object_no INTEGER; row_id ROWID; ...BEGIN
CHỌN ROWID INTO row_id FROM emp WHERE empno = 7499; object_no: = DBMS_ROWID.ROWID_OBJECT (row_id); DBMS_OUTPUT.PUT_LINE ('Số obj. # Là ' || object_no); ...