I need something like:
SELECT PARTITION_NAME,
to_char(LONG_TO_TIMESTAMP(HIGH_VALUE), 'MM/DD/YYYY HH24:MI:SS') AS HIGH_VAL
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = 'TABLE_NAME'
Output should look something like this:
PARTITION_NAME HIGH_VAL ---------------- -------------------- SOME_NAME 01/01/2010 00:00:00
When I run:
SELECT PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS
It looks like:
PARTITION_NAME HIGH_VAL ---------------- -------------------- SOME_NAME TIMESTAMP' 2010-01-01 00:00:00'
If I use UTL_RAW.CAST_TO_VARCHAR2(HIGH_VALUE)
,
I end up getting an ORA-00997: illegal use of LONG datatype
error.
If I use ''||HIGH_VALUE
or to_clob(HIGH_VALUE)
or to_char(HIGH_VALUE)
,
I get an ORA-00932: inconsistent datatypes: expected [DATA_TYPE] got LONG
error
My working function thanks to shobi:
CREATE OR REPLACE FUNCTION GET_HIGH_VALUE_AS_DATE (
p_TableName IN VARCHAR2,
p_PatitionName IN VARCHAR2
) RETURN DATE
IS
v_LongVal LONG;
BEGIN
SELECT HIGH_VALUE INTO v_LongVal
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = p_TableName
AND PARTITION_NAME = p_PatitionName;
RETURN TO_DATE(substr(v_LongVal, 11, 19), 'YYYY-MM-DD HH24:MI:SS');
END GET_HIGH_VALUE_AS_DATE;
SQL Looks like
SELECT PARTITION_NAME, GET_HIGH_VALUE_AS_DATE(TABLE_NAME, PARTITION_NAME)
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME LIKE 'TABLE_NAME'
AND ROWNUM < 2;
Oracle has expanded on the DATE datatype and has given us the TIMESTAMP datatype which stores all the information that the DATE datatype stores, but also includes fractional seconds. If you want to convert a DATE datatype to a TIMESTAMP datatype format, just use the CAST function.
The maximum length for VARCHAR2 is 32672 BYTE or 8168 CHAR which is the same as the maximum length for VARCHAR of 32672 OCTETS or 8168 CODEUNITS32. Similarly, when the NVARCHAR2 data type is explicitly encountered in SQL statements, it is implicitly mapped following the same rules as the NVARCHAR data type.
To convert a NUMBER to a TIMESTAMP you can use an expression like TO_TIMESTAMP(TO_CHAR(...)) . To compute the number of seconds between two timestamps, one solution is to cast both to dates, and substract them : you will get a (decimal) result in days, which can be then converted to seconds.
TO_CHAR (number) converts n to a value of VARCHAR2 datatype, using the optional number format fmt . The value n can be of type NUMBER , BINARY_FLOAT , or BINARY_DOUBLE . If you omit fmt , then n is converted to a VARCHAR2 value exactly long enough to hold its significant digits.
The only way to convert LONG columns is in PL/SQL. Look at the following example, which determines the length of the LONG field:
SET SERVEROUTPUT ON SIZE 10000;
DECLARE
long_var LONG;
BEGIN
SELECT text_column INTO long_var
FROM table_with_long
WHERE rownum < 2;
DBMS_OUTPUT.PUT_LINE('The length is '||LENGTH(long_var));
END;
Basically, you define a variable as the LONG type, then SELECT the column INTO the variable. Finally, it is output to the user. SET SERVEROUTPUT ON SIZE 10000 allows spooling from the PUT_LINE to go to the screen.
You can use a similar method to select the LONG into a varchar field. The following example puts the first 2000 characters into TABLE_B, which for our purposes has one column, TEXT_FIELD:
DECLARE
long_var LONG;
var_var VARCHAR2(2000);
BEGIN
SELECT text_column INTO long_var
FROM table_with_long
WHERE rownum < 2;
var_var := substr(long_var,1,2000);
INSERT INTO table_b
VALUES (var_var);
END;
There's a good trick to do this using dynamic sql ( EXECUTE IMMEDIATE
)
SET SERVEROUTPUT ON
DECLARE
l_date DATE;
BEGIN
FOR r IN (
SELECT partition_name,high_value
FROM user_tab_partitions
WHERE table_name = 'MYTABLE'
) LOOP
EXECUTE IMMEDIATE 'BEGIN :v := ' || r.high_value || '; END;'
USING OUT l_date;
DBMS_OUTPUT.PUT_LINE(r.partition_name||','|| l_date);
END LOOP;
END;
/
This produces an output of the form
SYS_P601452,19-10-18 --(partition_name,high_value)
SYS_P601451,18-10-18
SYS_P601453,20-10-18
SYS_P601454,21-10-18
SYS_P601455,22-10-18
..
..
Here I used a DATE
type partitioned column. You may use a TIMESTAMP
variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With