Jak Posortować Dane Typu LONG

Rzadko choć niewykluczone, że na ‘już’ konieczne będzie posortowanie danych typu LONG, nawet jeżeli Oracle odchodzi od używania tego typu i namawia do przejścia na typ CLOB. Sam jednak wycofuje ten typ w sposób właściwy dla większości podmiotów korporacyjnych czyli baaaaaardzo opieszale.

Takim przykładem jest choćby kolumna HIGH_VALUE w tabelach *TAB_PARTITIONS, która to przechowuje informacje o rozkładzie danych w tabeli, a która jest typem LONG.

DROP TABLE T1 PURGE
/

CREATE TABLE T1(id NUMBER, creation_date DATE)
PARTITION BY RANGE(creation_date)(
  PARTITION p_13 VALUES LESS THAN (TO_DATE('20230513','YYYYMMDD')),
  PARTITION p_14 VALUES LESS THAN (TO_DATE('20230514','YYYYMMDD')),
  PARTITION p_15 VALUES LESS THAN (TO_DATE('20230515','YYYYMMDD')),
  PARTITION p_16 VALUES LESS THAN (TO_DATE('20230516','YYYYMMDD')),
  PARTITION p_17 VALUES LESS THAN (TO_DATE('20230517','YYYYMMDD')),
  PARTITION p_max VALUES LESS THAN (MAXVALUE)
)
/


SELECT table_name,
       partition_name,
       high_value
  FROM user_tab_partitions
where table_name = 'T1'
/
TABLE_NAME PARTITION_NAME HIGH_VALUE <-- TYP LONG
---------- -------------- ----------
   T1	      P_13        TO_DATE(' 2023-05-13 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
   T1	      P_14	      TO_DATE(' 2023-05-14 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
   T1	      P_15	      TO_DATE(' 2023-05-15 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
   T1	      P_16	      TO_DATE(' 2023-05-16 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
   T1	      P_17	      TO_DATE(' 2023-05-17 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
   T1	      P_MAX	      MAXVALUE

Chcąc posortować rekordy w tabeli względem kolumny HIGH_VALUE nie można posłużyć się zwykłym ORDER BY ot tak. Konieczne jest zastosowanie dodatkowego mechanizmu, które wyciągnie wartość z typu LONG i umożliwi konwersję na typ bardziej przyjazny programiście.

SELECT table_name,
       partition_name, 
       TO_DATE(substr(to_char(sys_dburigen(table_name, partition_name, high_value, 'text()').getclob()),12,10),'YYYY-MM-DD') as high_date
  FROM user_tab_partitions
 WHERE table_name = 'T1'
ORDER BY high_date ASC NULLS LAST 
/
TABLE_NAME PARTITION_NAME HIGH_VALUE
---------- -------------- ----------
  T1	      P_13        13-MAY-23 12.00.00
  T1	      P_14	  14-MAY-23 12.00.00
  T1	      P_15	  15-MAY-23 12.00.00
  T1	      P_16	  16-MAY-23 12.00.00
  T1	      P_17	  17-MAY-23 12.00.00
  T1	      P_MAX	  (null)

W powyższym przykładzie sortowanie ma miejsce rosnąco z uwzględnieniem partycji P_MAX, która to określa zakres od góry, stąd konieczność zastosowania NULLS LAST. Wykorzystując takie rozwiązanie dość szybko wyciąga się zawartość, konwertuje i sortuje typy LONG.

Szymon

Komentarze |0|

Legenda *) Pola oznaczone gwiazdką są wymagane
**) Możesz używać tych znaczników i atrybutów HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>