Как вы конвертируете ДОЛГОВЫЕ данные в TIMESTAMP или VARCHAR2?

Мне нужно что-то вроде:

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'

Результат должен выглядеть примерно так:

PARTITION_NAME HIGH_VAL
---------------- --------------------
SOME_NAME 01/01/2010 00:00:00

Когда я запускаю:

SELECT PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS

Похоже:

PARTITION_NAME HIGH_VAL
---------------- --------------------
SOME_NAME TIMESTAMP '2010-01-01 00:00:00'

Если я использую UTL_RAW.CAST_TO_VARCHAR2(HIGH_VALUE), Я получаю ошибку ORA-00997: illegal use of LONG datatype.

Если я использую ''||HIGH_VALUE или to_clob(HIGH_VALUE) или to_char(HIGH_VALUE), Я получаю ошибку ORA-00932: inconsistent datatypes: expected [DATA_TYPE] got LONG

Моя рабочая функция благодаря 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 Похож на

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;
2 ответа

Единственный способ конвертировать столбцы LONG - в PL/SQL. Посмотрите на следующий пример, определяющий длину поля LONG:

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;

В принципе, вы определяете переменную как тип LONG, затем выбираете столбец INTO переменной. Наконец, он выводится пользователю. SET SERVEROUTPUT ON SIZE 10000 позволяет наматывать из PUT_LINE на экран.

Вы можете использовать аналогичный метод для выбора LONG в поле varchar. Следующий пример помещает первые 2000 символов в TABLE_B, который для наших целей имеет один столбец, 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;


Также можно было бы сделать следующее:

CREATE TABLE long_to_clob
( partition_name VARCHAR2(30)
, high_value_clob CLOB
, high_value_text VARCHAR2(4000)
);
INSERT INTO long_to_clob (partition_name, high_value_clob)
SELECT partition_name, TO_LOB(high_value)
 FROM user_tab_partitions;
UPDATE long_to_clob
 SET high_value_text = DBMS_LOB.SUBSTR(high_value_clob, 1, 4000);

Единственное предостережение с использованием TO_LOB заключается в том, что оно должно использоваться в инструкции INSERT, как указано выше. С другой стороны, существует меньше ограничений на использование пакета DBMS_LOB. Очевидно, как только вы получите значение в столбце VARCHAR2, вы можете делать с ним все, что хотите.

Надеюсь, что это поможет.

licensed under cc by-sa 3.0 with attribution.