Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie kann man bei einem bekannten Partitionsschlüsselwert in Oracle feststellen, in welche Partition eine Zeile gehen würde?

Mit diesen Testdaten

INSERT INTO foos VALUES (1234, SYSDATE);
INSERT INTO foos VALUES (1235, SYSDATE);
INSERT INTO foos VALUES (1236, SYSDATE);

Wie hier beschrieben https://jonathanlewis.wordpress.com/2009/11 /21/ora_hash-Funktion/

du bekommst

with hsh as (
select  BATCH_ID, ora_hash(BATCH_ID, 3)+1 subpartition_position  from foos)
select BATCH_ID, SUBPARTITION_POSITION,
(select subpartition_name from   user_tab_subpartitions where   table_name = 'FOOS' and SUBPARTITION_POSITION = hsh.SUBPARTITION_POSITION) subpartition_name
from hsh;

  BATCH_ID SUBPARTITION_POSITION SUBPARTITION_NAME            
---------- --------------------- ------------------------------
      1236                     1 R0_H0                          
      1235                     3 R0_H2                          
      1234                     4 R0_H3   

Beachten Sie, dass der Parameter 3 in ora_hash ist die Anzahl der (Unter-)Partitionen abzüglich 1. (=4-1). Sie müssen eine zusätzliche Verarbeitung durchführen, wenn die Anzahl der Partitionen keine Zweierpotenz ist (was nicht empfohlen wird), wie in der Referenz beschrieben.

Sie können das Ergebnis mit einer expliziten Partitionsabfrage wie unten verifizieren

select * from foos subpartition( R0_H0 ); --   1236
select * from foos subpartition( R0_H1 ); --   empty
select * from foos subpartition( R0_H2 ); --   1235
select * from foos subpartition( R0_H3 ); --   1234

Und natürlich funktioniert es auch für neue Schlüssel, neu für 1237 was nicht in der Tabelle ist.

with hsh as (
select  1237 BATCH_ID, ora_hash(1237, 3)+1 subpartition_position  from dual)
select BATCH_ID, SUBPARTITION_POSITION,
(select subpartition_name from   user_tab_subpartitions where   table_name = 'FOOS' and SUBPARTITION_POSITION = hsh.SUBPARTITION_POSITION) subpartition_name
from hsh;

  BATCH_ID SUBPARTITION_POSITION SUBPARTITION_NAME            
---------- --------------------- ------------------------------
      1237                     2 R0_H1 

Die "vorhergesagte" Unterpartition ist R0_H1 , mal sehen, wohin das INSERT geht:

INSERT INTO foos VALUES (1237, SYSDATE);      
select * from foos subpartition( R0_H1 ); --  1237

Aber mit Vorsicht verwenden, da es meiner Meinung nach keine dokumentierte Funktion ist ...