【问题标题】:Line break in dbms_output.put_linedbms_output.put_line 中的换行符
【发布时间】:2023-03-20 09:53:01
【问题描述】:

我在 cursor 的帮助下运行一些 Oracle 程序,并通过 dbms_output.put_line 在日志文件中获取输出。

我想做的是在 server_name 上换行,dbms_output.put_line 可以吗?

目前它会将所有看起来不整洁的东西都列在一起。

还有一些服务器 id 显示为 1234.9 或 1234.88,是否可以设置像 999.99 这样的 numformat?不知怎的,我不能在过程中做col server_id for 999.99

create procedure proc (vServer IN VARCHAR2, vServerID IN NUMBER)

IS
CURSOR curTable
IS

SELECT server_name, server_id
FROM tab1
WHERE server_name = vServer
and server_id = vServerID;

BEGIN

FOR rec1 IN curTable
LOOP

dbms_output.put_line(rec1.server_name || '   '|| rec1.server_id);

END LOOP;

END proc;

所需输出示例:

S1    1234
S1    1234
S1    1234

S2    5678
S2    5678

【问题讨论】:

  • 您是否有理由在 PL/SQL 中执行此操作,而不是作为简单的 SQL commad - 也许使用 SQL*Plus 格式化命令?
  • 我同意并提出了简单的 SQL,但对于多用户访问,它需要在程序中。
  • 不确定我是否理解您的意思...但是,您传递的是单个服务器名称和 ID,那么您将如何在输出中获得不同的服务器?

标签: oracle stored-procedures dbms-output


【解决方案1】:

仅当您将该列指定为排序顺序时,对 server_id 进行中断才有意义。然后,您必须自己编写中断逻辑。此外,您可以根据需要使用 TO_CHAR 来格式化数字。

这是应该做你想做的代码:

create procedure proc (vServer IN VARCHAR2, vServerID IN NUMBER)

IS
CURSOR curTable
IS

SELECT server_name, server_id
FROM tab1
WHERE server_name = vServer
and server_id = vServerID
ORDER BY server_id ;

l_last_server_id tab1.server_id%TYPE := 0;

BEGIN

FOR rec1 IN curTable
LOOP

-- Test for break:
IF last_server_id != rec1.server_id THEN
  -- Break detected:
  dbms_output.put_line('---'); -- DBMS_OUTPUT will not print a blank line.
END IF ;

dbms_output.put_line(rec1.server_name || '   '|| TO_CHAR(rec1.server_id,'999.99');

l_last_server_id := rec1.server_id ;

END LOOP;

END proc;

【讨论】:

  • K,不知道为什么这对我不起作用。我正在提供 schemaname.tab1.server 并且也尝试过没有 schemaname 但仍然没有运气。运行查询的用户可以访问属于另一个用户的表 tab1。 l_last_server_id schemaname.tabl1.sever_id%TYPE := 0; 也可以将 lpad 与 TO_CHAR 一起使用吗? to_char(lpad(rec1.server_id, '999.99',7))
  • 好的,它现在可以工作了,我试图打印空行,所以它最初失败了。我们如何才能同时使用 lpad 和 to_char 呢?
  • “DBMS_OUTPUT 不会打印空行”不正确;客户可能会压制它。在 SQL*Plus 中,如果您使用set serveroutput on format wrapped 而不是默认的word_wrapped,那么您将看到空白行以及前导空格。 Read more。但你也可以使用dbms_output.new_line
  • 要获得空白行,我们也可以使用 dbms_output.put(CHR(10)); ,感谢 Alex P. 格式包装的注释。
【解决方案2】:

这似乎是您对普通 SQL 所做的事情,但假设这是一个 PL/SQL 练习,您可以使用一个变量来跟踪最后看到的值,并在它发生变化时添加一个额外的行:

...
  last_server_name tab1.server_name%type;

BEGIN

  FOR rec1 IN curTable
  LOOP
    if last_server_name is not null
        and rec1.server_name != last_server_name then
      dbms_output.new_line;
    end_if;

    dbms_output.put_line(rec1.server_name
      || '   '|| to_char(rec1.server_id, '99990.00'));

    last_server_name := rec1.server_name;
  END LOOP;

END proc;

您可以在dbms_output 调用中使用to_char(),使用任何适合的格式模型 - 无论如何您都在进行隐式转换;或者如果您没有将 ID 定义为循环中的数字,则在光标中。

请记住,如果您的客户端已设置好,您只会看到输出 - 例如,使用 set serveroutput on。您通常不能依赖它,因此在实际代码中使用dbms_output 来进行除调试之外的任何事情都不是一个好主意。

正如 Scott K. 指出的那样,您需要订购游标结果才能使其工作,因此将 order by server_name 添加到游标查询中。除了,您在过滤vServervServerID 时只是在寻找单个服务器名称和ID,因此您的原始查询无论如何都无法产生原始输出...

【讨论】:

  • 是的,在使用 vServerName 过滤时,示例查询可能不是最好的示例,我确实接受不同的值来列出所有服务器,但为了简单起见,我使用了 ServerName 但忘记了我接受带 IN 参数。我会根据您的建议进行测试。
猜你喜欢
  • 1970-01-01
  • 2012-12-05
  • 2011-06-22
  • 2018-10-24
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
相关资源
最近更新 更多