7

私は次のように間隔パーティションとリストサブパーティションを備えたOracle11テーブルを使用しています(簡略化):

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')));

サブパーティションの(システム生成された)名前を知らずに、特定の月の特定のサブパーティションを削除するにはどうすればよいですか?「altertable...drop subpartition for(subpartition_key_value、...)」という構文がありますが、サブパーティションを削除する月を指定する方法がわかりません。パーティション管理ガイドにも例はありません。8-}

4

3 に答える 3

3

結局のところ、「subpartition for」構文は実際に機能しますが、それはOracleがあなたに伝えたくない秘密のようです。:-)

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

これにより、MSG_TIME2010/02/01およびMSG_NRFOOを含むサブパーティションが削除されます。(この正確なMSG_TIMEおよびMSG_NRを持つ実際の行がある必要はありません。ただし、そのようなサブパーティションがない場合はエラーがスローされます。)

于 2012-09-12T12:17:14.703 に答える
3

メタデータテーブルを使用して、特定のサブパーティション名を取得できます。

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.

パーティションを動的にドロップする場合は、列のクエリが簡単でない可能性があるALL_TAB_SUBPARTITIONSため、ビューでパーティションを見つけるのが難しい場合があります。HIGH_VALUEその場合、特定の行DBMS_ROWIDのサブパーティションを見つけるために使用できます。object_id

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
于 2012-09-11T08:40:09.413 に答える
1

投稿してくれてありがとう-それは私にとって非常に役に立ちました。

パーティションを識別して削除するための上記のスクリプトに関する1つの観察:

object_idによって返されるのはテーブルのものでdbms_rowid.rowid_infoはありません。実は。通常、これらのIDは一致することが観察されます。ただし、パーティションテーブルを数回切り捨てた後、これらのIDはデータベース内で分岐しました。したがって、代わりにを使用してパーティションの名前を見つけるのが合理的かもしれません。object_idall_objectsdata_object_iddata_object_id

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

From the table description of ALL_OBJECTS:

OBJECT_IDオブジェクトのオブジェクト番号DATA_OBJECT_IDオブジェクトを含むセグメントのオブジェクト番号

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

上記のリンクで提供されているサンプルコードでは、DBMS_ROWID.ROWID_OBJECT(row_id)代わりに、で指定されているのと同じ情報を導出するために使用されていdbms_rowid.rowid_infoます。ただし、このサンプルに関するドキュメントには、ROWIDからのデータオブジェクト番号であると記載されています。

この例では、EMPテーブルの行のROWIDを返し、DBMS_ROWIDパッケージのROWID_OBJECT関数を使用してROWIDからデータオブジェクト番号を抽出し、オブジェクト番号を表示します。

DECLARE object_no INTEGER; row_id ROWID; ... BEGIN
SELECT ROWID INTO row_id FROM emp WHERE empno = 7499; object_no:= DBMS_ROWID.ROWID_OBJECT(row_id); DBMS_OUTPUT.PUT_LINE('オブジェクト#は' || object_no); ..。

于 2013-06-14T20:04:18.627 に答える