SQL 开发人员假脱机:如何摆脱第一个空行

SQL Developer spooling: how to get rid of the first, empty line

我在 Oracle SQL Developer 4.1 中使用以下假脱机脚本:

set echo off
set feedback off
set termout off

spool A.txt
select /*csv*/ * from A where rownum <= 1000;
spool off

spool B.txt
select /*csv*/ * from B where rownum <= 1000;
spool off

...

但是假脱机输出文件的开头包含一个空行。

这与 sqlplus spooling: How to get rid of first, empty line? 中详述的问题相同。我尝试使用 SET NEWPAGE NONE 但是,从 SQL Developer 4.1.2 开始,这只会导致错误消息并且输出格式没有变化:

SP2-0158: unknown SET option "newpage"

有什么方法可以抑制 SQL Developer 中第一个空行的输出?

这似乎不可能;之前有人问过,但我没有看到任何解决方案。 (尝试使用 set sqlformat csv 而不是 /*csv*/ 提示,以防万一,但行为是相同的)。

如果您将网格中的查询结果导出为 CSV(右键单击网格并选择“导出...”),那么您不会得到空白行,但这显然是脚本之外的手动过程,所以不完全等同。

选项似乎是 post- 处理文件以删除空白行,从网格中导出,或者 运行 您的脚本使用 SQL*Plus。 None 其中看起来很理想。

两件事:

  1. 这是默认的 SQL*Plus 行为,我们会尽可能地 100% 模仿它
  2. 有一个错误 - 我们不支持 SET PAGESIZE 0。如果您将它与 SET TRIMSPOOL ON 结合使用,您将丢失空白行

我们已将其列入下一个版本的列表

2020 更新

使用 SQL Developer 的 20.2 版,您的脚本按预期工作

不幸的是,我在 SQLcl(SQLDev 的命令行版本)20.2 版中看到了这个问题,但由于今年夏天早些时候一些人在 Twitter 上的反馈,它已在 20.3 中得到修复。

这是 SQLcl 20.3 发布后一个月左右的样子

10:38:34 nolog >show version
Oracle SQLDeveloper Command-Line (SQLcl) version: 20.3.0.0 build: 20.3.0.240.1605
10:40:31 nolog >set echo off
10:40:49 nolog >set feedback off
10:40:52 nolog >set termout off
10:40:56 nolog >spool A.txt
10:41:04 nolog >select /*csv*/ * from regions;
"REGION_ID","REGION_NAME"
1,"Europe"
2,"Americas"
3,"Asia"
4,"Middle East and Africa"
10:41:14 nolog >spool off
10:41:19 nolog >exit

Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

c:\SQLDev\sqlcl.3-lines\sqlcl\bin>type A.txt
"REGION_ID","REGION_NAME"
1,"Europe"
2,"Americas"
3,"Asia"
4,"Middle East and Africa"

c:\SQLDev\sqlcl.3-lines\sqlcl\bin>

正如 thatjeffsmith 亲切指出的那样,希望这个错误在下一个版本中得到修复。在此之前,您可以使用 SQLcl(现代 SQL*Plus 包含并由 SQLDeveloper 4.1.2 使用)与 SED 脚本一起完成所需的结果。

SQLcl 位于此处:$SQLDEV_HOME\sqldeveloper\bin\sql。 $SQLDEV_HOME 只是您安装的 SQLDeveloper 版本的目录。

在您的示例中,您从单个 SQL 文件生成两个单独的输出文件,A.txt 和 B.txt。我提出的以下方法要求将其分成两个单独的 SQL 文件:A.sql 和 B.sql.

A.sql:

set echo off
set feedback off
set termout off
select /*csv*/ * from A where rownum <= 1000;

B.sql:

set echo off
set feedback off
set termout off
select /*csv*/ * from B where rownum <= 1000;

下面是我的名为"remove-first-blank-line.sed"的SED脚本的一行内容:

0,/^$/{//d}

"0," 定义以下命令块将仅应用于第一行。

"/^$/" 定义要匹配的正则表达式模式。 “^”是行的开始,“$”是行的结束标记,所以这个模式只匹配完全没有内容的行,没有 spaces...什么都没有。如果你想删除可能包含 whitespace(制表符,spaces)的行,那么你可能想试试这个 SED 命令:0,/^[[:space:] ]*$/{//d}

"//d" 定义脚本是删除找到的匹配模式。

有关此 SED 脚本的更多详细信息,请参阅:https://unix.stackexchange.com/questions/75424/remove-only-the-first-blank-line-sed

因此,要从每个 SQL 文件、A.sql 和 B.sql 的输出中删除第一个空行,必须使用 SQLcl 和那么输出必须通过以下 SED 脚本从 SQLcl 进行管道传输,如下所示:

$SQLDEV_HOME\sqldeveloper\bin\sql -s scott/tiger@XE @A.sql | sed -f remove-first-blank-line.sed > A.txt
$SQLDEV_HOME\sqldeveloper\bin\sql -s scott/tiger@XE @B.sql | sed -f remove-first-blank-line.sed > B.txt

“-s”是 SQLcl 的 "silent" 选项(类似于 SQL*Plus),它确保没有数据库登录信息输出使您的输出混乱文件。

“|”字符通过给定的 SED 脚本从 SQLcl 输出所有的输出。

“>”将 SED 脚本的所有输出写入您的输出文件 "mysql.out"。如果您需要使用另一个 SQL 脚本将更多数据附加到同一文件,请使用“>>”以便您可以将数据附加到文件而不是覆盖文件。

注意:是的,您也可以直接在命令行上使用 SED 命令,但这通常需要以不同的方式转义特殊字符,具体取决于您 OS 所在的 运行。我发现当我将 SED 命令保存在简短且命名良好的 SED 脚本文件中时,我更有可能在各种平台(例如 Linux 和 Windows)中重复使用我的 SED 脚本.