【问题标题】:How do I view a CLOB output parameter in TOAD from an Oracle Stored Procedure?如何从 Oracle 存储过程中查看 TOAD 中的 CLOB 输出参数?
【发布时间】:2025-12-11 04:30:01
【问题描述】:

我在 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;

不要忘记作为脚本执行,而不仅仅是执行语句,结果会出现在 DBMS 输出窗口中,而不是数据网格中。

【问题讨论】:

  • 这对您有帮助吗:*.com/questions/3790379/…
  • @JorgeCampos 我尝试将 DBMS_LOB.SUBSTR 写入表并读出,但结果仍与 dbms_output.put_line 相同
  • 您确定返回的CLOB 中实际上还有更多内容吗?您可以使用dbms_lob.getlength(your_clob)CLOB 的长度打印到标准输出并查看它是否比<MyXMLElement></MyXMLElement> 的长度长吗?
  • @PrzemyslawKruglej Aaaaaaaaaaaarrrrrrrrrggggggghhhhhhhhhh 这促使我做更多的挖掘,似乎 INPUT 参数已从日期更改为某些特定格式的 varchars。当我从存储的 proc 中取出 select 并运行它时,它运行良好,但是当我在输入参数中包含日期格式时 - 只得到了那个空的 xml 字符串!谢谢大佬!
  • 没问题,我很高兴能帮上忙 :)

标签: sql oracle stored-procedures toad clob


【解决方案1】:

插入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;

【讨论】:

  • 我只是得到和 DBMS_OUTPUT.PUT_LINE(my_output_parameter) 一样的东西?
  • @JumpingJezza 您可以像DBMS_OUTPUT 一样获得完整的 CLOB 内容。脚本按 200 个字符的部分顺序将 CLOB 的内容传递给 DBMS_OUTPUT.Put
  • 一旦我将输入参数设置为新格式​​,它就起作用了!我只想补充一点,我必须“作为脚本执行”,而不仅仅是“执行语句”。
【解决方案2】:

您是否考虑将CLOB 作为结果集打印?然后,您可以使用 PIPELINED 函数(更多关于它们的信息:PIPELINED functions by Tim Hall),它将逐行返回 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
-------------------------
第一行
第二行,更长的
第三

在 SQLFiddle 检查它:SQLFiddle example

【讨论】:

    【解决方案3】:

    我猜 DBMS_OUTPUT.PUT_LINE 的内部行限制为 255 个字符。但是,它已从 10g 第 2 版开始删除。您可以尝试在表中插入列数据,稍后通过查询该表来查看。

    请参考-

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

    【讨论】:

    • 11g R2内部限制为2000行。
    • 当我在数据库中没有太多权限时,写入临时表并查看它似乎是 1-off 的最佳选择。你有一个如何做到这一点的例子吗?我再次编辑了我的问题以显示我尝试失败的内容
    • 这里是步骤 - 1. CREATE TABLE param_log (param clob); 2.在得到out参数值后放入insert语句——--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);犯罪;结束;
    • 这不起作用 - 当我在表上进行选择时,我得到的结果与 DBMS_OUTPUT.PUT_LINE(my_output_parameter) 相同