I have found this sql that help avoid high_value long type column.
--VER HIGH VALUE
col partition_name for a30
col high_value for a120
col PARTITION for a20
WITH xml AS
(
SELECT dbms_xmlgen.getxmltype('SELECT table_name,partition_name,partition_position,high_value
FROM dba_tab_partitions
WHERE TABLE_OWNER = UPPER(''MY_SCHEMA'') ----MY SCHEMA HERE') AS x
FROM dual
)
SELECT extractValue(rws.object_value, '/ROW/TABLE_NAME') table_name,
extractValue(rws.object_value, '/ROW/PARTITION_NAME') partition,
extractValue(rws.object_value, '/ROW/HIGH_VALUE') high_value
FROM xml x, table(xmlsequence(extract(x.x, '/ROWSET/ROW'))) rws;
The sample output:
SAMPLE_TABLE P82 TO_DATE(' 2021-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P83 TO_DATE(' 2021-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P84 TO_DATE(' 2021-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P85 TO_DATE(' 2021-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P86 TO_DATE(' 2022-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P87 TO_DATE(' 2022-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P88 TO_DATE(' 2022-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P89 TO_DATE(' 2022-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P90 TO_DATE(' 2022-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P91 TO_DATE(' 2022-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P92 TO_DATE(' 2022-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P93 TO_DATE(' 2022-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P94 TO_DATE(' 2022-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P95 TO_DATE(' 2022-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P96 TO_DATE(' 2022-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P97 TO_DATE(' 2022-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SAMPLE_TABLE P98 MAXVALUE
How can I convert column high_value directly to a date
IE: instead of getting:
`TO_DATE(' 2022-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')`
I'd like to get:
2022-12-01
Or, if I change the date mask, I got:
alter session set nls_date_format = 'dd/mm/yyyy hh24:mi:ss';
01/12/2022 00:00:00
CodePudding user response:
With your sample output it looks like you need to extract substring of the HIGH_VALUE column from position 11, take 10 characters and convert it to date. The last row containing tekst 'MAXVALUE' should be handled too. Below is SQL that converts the dates and instead of MAXVALUE tekst results with the preceding row's date...
Select
TABLE_NAME,
PARTITION_NAME,
PARTITION_POSITION,
CASE WHEN HIGH_VALUE != 'MAXVALUE' THEN To_Date(SubStr(HIGH_VALUE, 11, 10), 'yyyy-mm-dd')
ELSE LAST_VALUE(To_Date(SubStr(HIGH_VALUE, 11, 10), 'yyyy-mm-dd')) OVER(ORDER BY PARTITION_NAME ROWS BETWEEN 1 PRECEDING And 1 PRECEDING)
END "HIGH_VALUE"
From
dba_tab_partitions
WHERE
TABLE_OWNER = UPPER(''''MY_SCHEMA'''')'
/*
R e s u l t :
TABLE_NAME PARTITION_NAME PARTITION_POSITION HIGH_VALUE
------------ -------------- ------------------ ----------
SAMPLE_TABLE P82 Null 01-SEP-21
SAMPLE_TABLE P83 Null 01-OCT-21
SAMPLE_TABLE P84 Null 01-NOV-21
SAMPLE_TABLE P85 Null 01-DEC-21
SAMPLE_TABLE P86 Null 01-JAN-22
SAMPLE_TABLE P87 Null 01-FEB-22
SAMPLE_TABLE P88 Null 01-MAR-22
SAMPLE_TABLE P89 Null 01-APR-22
SAMPLE_TABLE P90 Null 01-MAY-22
SAMPLE_TABLE P91 Null 01-JUN-22
SAMPLE_TABLE P92 Null 01-JUL-22
SAMPLE_TABLE P93 Null 01-AUG-22
SAMPLE_TABLE P94 Null 01-SEP-22
SAMPLE_TABLE P95 Null 01-OCT-22
SAMPLE_TABLE P96 Null 01-NOV-22
SAMPLE_TABLE P97 Null 01-DEC-22
SAMPLE_TABLE P98 Null 01-DEC-22
*/
Regards...
CodePudding user response:
You rather can use a dynamic SQL statement within a PL/SQL code block in order to be able to return desired date value after conversion from LONG to VARCHAR2 such as
DECLARE
v_dt DATE;
v_chr VARCHAR2(4000);
BEGIN
DBMS_OUTPUT.PUT_LINE('table_name partition_name high_value');
FOR c IN (
SELECT table_name,partition_name,partition_position,high_value
FROM user_tab_partitions
)
LOOP
v_chr := SUBSTR(c.high_value, 1, 4000);
EXECUTE IMMEDIATE 'SELECT '||v_chr||' FROM dual' INTO v_dt;
DBMS_OUTPUT.PUT(c.table_name||' ');
DBMS_OUTPUT.PUT(c.partition_name||' ');
DBMS_OUTPUT.PUT_LINE(v_dt);
END LOOP;
END;
/
CodePudding user response:
You may execute HIGH_VALUE
expression as dynamic SQL and obtain the date without any parsing.
create table t ( id int, dt date ) partition by range (dt) interval (interval '3' day) ( partition pmin values less than(date '2022-01-01') )
insert into t (id, dt) select level, date '2022-01-01' dbms_random.value(0,7)*level from dual connect by level < 10
with function f_evaluate_date_expr(p_expr varchar2) /*Evaluates date expression to avoid any manual parsing*/ return date as l_dt date; begin if p_expr = 'MAXVALUE' then l_dt := timestamp '9999-12-31 23:59:59'; else execute immediate 'select ' || p_expr || ' from dual' into l_dt; end if; return l_dt; end; select table_name, partition_name, f_evaluate_date_expr(high_value) as high_value from xmltable( '/ROWSET/ROW' passing dbms_xmlgen.getxmltype(' select table_name, partition_name, high_value from user_tab_partitions ') columns table_name varchar2(30), partition_name varchar2(30), high_value varchar2(100) )
TABLE_NAME | PARTITION_NAME | HIGH_VALUE |
---|---|---|
T | PMIN | 2022-01-01 00:00:00 |
T | SYS_P4420 | 2022-01-10 00:00:00 |
T | SYS_P4421 | 2022-01-13 00:00:00 |
T | SYS_P4422 | 2022-01-22 00:00:00 |
T | SYS_P4423 | 2022-01-28 00:00:00 |
T | SYS_P4424 | 2022-01-07 00:00:00 |
T | SYS_P4425 | 2022-01-31 00:00:00 |
T | SYS_P4426 | 2022-01-19 00:00:00 |