Не могли бы вы распечатать CLOB
в качестве результирующего набора? Затем вы можете использовать функцию PIPELINED
(подробнее о них здесь: Конвейерные функции Тим Холл), который будет возвращать CLOB
построчно, взгляните на пример ниже:
CREATE TABLE my_clob_tab (
id NUMBER,
clob_col CLOB
)
/
INSERT INTO my_clob_tab
VALUES (1,
to_clob('first line' || chr(10) ||
'second line, a longer one' || chr(10) ||
'third'))
/
CREATE OR REPLACE TYPE t_my_line_str AS TABLE OF VARCHAR2(2000)
/
CREATE OR REPLACE FUNCTION print_clob_func(p_id IN NUMBER)
RETURN t_my_line_str PIPELINED
AS
v_buffer VARCHAR2(32767);
v_clob CLOB;
v_len NUMBER;
v_offset NUMBER := 1;
v_line_break_pos NUMBER;
v_amount NUMBER;
BEGIN
SELECT clob_col
INTO v_clob
FROM my_clob_tab
WHERE id = p_id;
IF v_clob IS NOT NULL THEN
v_len := dbms_lob.getlength(v_clob);
WHILE v_offset < v_len
LOOP
v_line_break_pos := instr(v_clob, chr(10), v_offset);
IF v_line_break_pos = 0 THEN
v_amount := v_len - v_offset + 1;
ELSE
v_amount := v_line_break_pos - v_offset;
END IF;
dbms_lob.read(v_clob, v_amount, v_offset, v_buffer);
v_offset := v_offset + v_amount + 1;
PIPE ROW (v_buffer);
END LOOP;
END IF;
END;
/
(функция может быть изменена так, чтобы она принимала в качестве параметра CLOB
, который вы получаете от своей процедуры)
Код считывает содержимое CLOB
построчно (я предположил, что разделителем строк является CHR(10)
— если вы работаете в Windows, вы можете изменить его на CHR(10) || CHR(13)
) и PIPE
s каждой строки соответствует оператору SELECT
.
Функция, которая читает clob, также может печатать вывод на стандартный вывод через dbms_output.put_line
, но это будет сложнее, потому что вам придется учитывать, что максимальная длина строки стандартного вывода ограничена, поправьте меня, если я ошибаюсь , 2000 символов, но это выполнимо (к сожалению, сейчас я не могу попробовать это решение). А пока, пожалуйста, ознакомьтесь с приведенным выше предложением и дайте мне несколько отзывов, если это сработает для вас.
Вернемся к решению, теперь мы можем выполнить этот оператор SELECT
:
SELECT COLUMN_VALUE AS clob_line_by_line FROM TABLE(print_clob_func(1));
Что даст нам следующий вывод:
CLOB_LINE_BY_LINE
-------------------------
first line
second line, a longer one
third
Проверьте это на SQLFiddle: пример SQLFiddle
person
Przemyslaw Kruglej
schedule
01.11.2013
CLOB
действительно больше контента? Можете ли вы вывести длинуCLOB
в стандартный вывод, используя:dbms_lob.getlength(your_clob)
, и посмотреть, длиннее ли она, чем длина<MyXMLElement></MyXMLElement>
? - person Przemyslaw Kruglej   schedule 04.11.2013