Как просмотреть выходной параметр CLOB в TOAD из хранимой процедуры Oracle?

У меня есть хранимая процедура в пакете в базе данных Oracle, которая имеет 2 входных параметра + 1 выходной параметр CLOB. Как просмотреть вывод в Toad? (Желательно, чтобы пользователь имел только права на выполнение/выбор)

Решение:

DECLARE
   my_output_parameter CLOB;
BEGIN 
   my_package.my_stored_proc(1, 2, my_output_parameter);
   DBMS_OUTPUT.PUT_LINE(my_output_parameter);
END;

Не забудьте выполнить как сценарий, а не просто выполнить оператор, и результаты появятся в окне вывода СУБД, а не в сетке данных.


person JumpingJezza    schedule 29.10.2013    source источник
comment
Поможет ли это вам: stackoverflow.com/questions/3790379/   -  person Jorge Campos    schedule 02.11.2013
comment
@JorgeCampos Я попытался DBMS_LOB.SUBSTR записать в таблицу и прочитать ее, но все равно тот же результат, что и dbms_output.put_line   -  person JumpingJezza    schedule 04.11.2013
comment
Вы уверены, что в возвращенном CLOB действительно больше контента? Можете ли вы вывести длину CLOB в стандартный вывод, используя: dbms_lob.getlength(your_clob), и посмотреть, длиннее ли она, чем длина <MyXMLElement></MyXMLElement>?   -  person Przemyslaw Kruglej    schedule 04.11.2013
comment
@PrzemyslawKruglej Aaaaaaaaaaaarrrrrrrrrgggggghhhhhhhhhh Это побудило меня еще немного покопаться, и кажется, что параметры INPUT были изменены с дат на varchars для определенного формата. Когда я извлек выбор из хранимого процесса и запустил его, он работал нормально, но когда я включил форматирование даты во входные параметры, я получил только эту пустую строку xml! Спасибо чувак!   -  person JumpingJezza    schedule 05.11.2013
comment
Ничего страшного, рад, что был чем-то полезен :)   -  person Przemyslaw Kruglej    schedule 05.11.2013


Ответы (3)


Я предполагаю, что DBMS_OUTPUT.PUT_LINE имеет ограничение внутренней строки в 255 символов. Однако он был удален, начиная с 10g Release 2. Вы можете попробовать вставить данные столбца в таблицу и просмотреть их позже, запросив эту таблицу.

Пожалуйста, обратитесь -

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:146412348066

person Aditya Kakirde    schedule 29.10.2013
comment
Внутренний лимит составляет 2000 строк в 11g R2. - person Rachcha; 29.10.2013
comment
Запись во временную таблицу и просмотр ее кажутся лучшим вариантом для одноразового использования, когда у меня не так много разрешений в базе данных. У вас есть пример того, как это сделать? Я снова отредактировал свой вопрос, чтобы показать, что я безуспешно пытался - person JumpingJezza; 30.10.2013
comment
Вот шаги: 1. CREATE TABLE param_log (param clob); 2. Поместите оператор вставки после получения значения параметра out -- --CREATE GLOBAL TEMPORARY TABLE temp_results (dataStuff CLOB); ОБЪЯВИТЬ my_output_parameter CLOB; НАЧАЛО my_package.my_stored_proc(1, 2, my_output_parameter); вставить в param_log значения (my_output_parameter); совершить; КОНЕЦ; - person Aditya Kakirde; 30.10.2013
comment
это не работает - когда я делаю выбор в таблице, я просто получаю то же самое, что и DBMS_OUTPUT.PUT_LINE(my_output_parameter) - person JumpingJezza; 31.10.2013

Не могли бы вы распечатать 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)) и PIPEs каждой строки соответствует оператору 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

Подход со вставкой блока PL/SQL и dbms_output:

DECLARE
   my_output_parameter CLOB;
BEGIN 
   my_package.my_stored_proc(1, 2, my_output_parameter);

  declare 
    vClob CLOB := my_output_parameter;
    vPos  number;
    vLen  number;
  begin
    vLen := DBMS_LOB.GetLength(vClob);
    vPos := 1;
    while vPos < vLen loop
      DBMS_OUTPUT.Put(DBMS_LOB.Substr(vCLOB, 200, vPos));
      vPos := vPos + 200;  
    end loop;
    DBMS_OUTPUT.new_line;
  end;

END;
person ThinkJet    schedule 02.11.2013
comment
Я просто получаю то же самое, что и DBMS_OUTPUT.PUT_LINE(my_output_parameter)? - person JumpingJezza; 04.11.2013
comment
@JumpingJezza Вы получаете полный CLOB-контент так же, как и DBMS_OUTPUT. Скрипт последовательно передает содержимое CLOB в DBMS_OUTPUT.Put порциями по 200 символов. - person ThinkJet; 04.11.2013
comment
Как только я исправил свои входные параметры в новом формате, это сработало! Я бы просто добавил, что мне нужно было «выполнить как скрипт», а не просто «выполнить оператор». - person JumpingJezza; 05.11.2013