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