关于 Oracle PL/SQL 引号运算符中的换行符:可以更改默认行为吗?

Posted

技术标签:

【中文标题】关于 Oracle PL/SQL 引号运算符中的换行符:可以更改默认行为吗?【英文标题】:About new line characters in Oracle PL/SQL quote operator: can the default behaviour be changed? 【发布时间】:2019-08-25 16:14:20 【问题描述】:

今天我注意到引用运算符的一些有趣之处。

在这里,我通过 SQL*Plus 在我的 Windows 10 笔记本电脑上运行的 12.1 数据库上运行此代码。

newline_CRLF.sql

set serveroutput on
declare
  l_str1   varchar2(100 char);
  l_str2   varchar2(100 char);
begin
  l_str1 := q'This is a
two lines string';
  l_str2 := 'This is a'||chr(13)||chr(10)||'two lines string';
  dbms_output.put_line('STR1: length='||length(l_str1)||', lengthb='||lengthb(l_str1));
  dbms_output.put_line('STR1: length='||length(l_str2)||', lengthb='||lengthb(l_str2));
end;
/

此代码位于一个文件中,其中行终止符是 CRLF 作为 Windows 中的默认值。

SQL> @newline_CRLF
STR1: length=26, lengthb=26
STR1: length=27, lengthb=27

Procedura PL/SQL completata correttamente.

我在这里注意到的是,引号运算符 q'' 中的换行符被解析为 Unix 样式的换行符。

我使用 Notepad++ EOL Conversion 实用程序将脚本转换为使用 Unix 样式的换行符,并且在下一次运行时我得到了相同的结果。

这绝对是有道理的,因为它保证任何代码库都以相同的方式处理,与 PL/SQL 语言 EOL 无关:如果不是这样,它可能会遇到错误。

这种行为非常适合类 Unix 系统,但在 Windows 上可能有点烦人,需要明确使用字符串连接。

这不是一个实际的问题,只是出于好奇而问:

“有人知道这是接受它的情况还是有可能设置一个参数来改变它的行为方式?”

考虑到我在 Windows 平台上获得了 LF,但到目前为止我在 MOS 上一无所获,我几乎不认为这是可能的,但你永远不知道......

【问题讨论】:

这也取决于编辑器,SQL*Plus 是否将换行符转换为 Unix 样式是未知的。我相信它确实如此,因为我怀疑 Oracle 是否对它们做任何事情(任何字符在 AQM 字符串中都是有效的,换行也不例外,无论是 Unix 还是 Windows)。如果我是你,我会坚持写'this is a' || chr(13) || chr(10) || 'two lines string',因为我不喜欢操作系统/编辑器选择我的脚本生成的内容。 【参考方案1】:

这是一个“接受它”的情况。除非您正在处理特定的错误,否则您应该接受这些怪癖而不是避免使用多行字符串。

在 SQL 和 PL/SQL 中,我几乎从未见过由多行字符串换行引起的问题。理论上的问题,是的,但没有现实世界的问题。事实上,如果你试图强迫每个人都使用明确的换行符,你更有可能遇到其他更奇怪的问题。

例如,我已经多次看到以下错误。如果您不小心只使用了 CHR(13),在 Windows DOS 提示符之类的环境中,它会导致奇怪的行为。如果您考虑一下旧类型编写器过去工作的时间,这个输出实际上是有道理的 - 您将栏拉回 (13),然后移至新行 (10)。但是,如果您只拉动栏 (13) 并开始输入,您将输入之前的字符。

SQL> set serveroutput on;
SQL> begin
  2     dbms_output.put_line('Where did this first line go?'||chr(13)||'Nothing to see here.');
  3  end;
  4  /
Nothing to see here. line go?

PL/SQL procedure successfully completed.

SQL>

更重要的是,充满字符串连接的代码看起来可怕。人们讨厌动态 SQL 的很大一部分原因是因为它看起来很丑。但它看起来很丑,因为人们连接和转义字符串。使用多行字符串、替代引用机制(您已经在使用)和一些REPLACE 函数,我们可以使代码动态且仍然可读。

与其他语言不同,动态代码在 PL/SQL 中是一件好事。如果我们不自觉地避免动态 SQL,我们的程序将受到严重限制,因为我们的连接字符串看起来很丑。

【讨论】:

我完全同意。我唯一不喜欢 REPLACE 解决方案的一点是,它是一个我很想避免的消耗 CPU 的任务,但可以肯定它是一个干净且简单的解决方案。

以上是关于关于 Oracle PL/SQL 引号运算符中的换行符:可以更改默认行为吗?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle Pl/SQL 中用户定义运算符背后的动机

去掉PowerDesigner生成SQL脚本中字段名带的引号

=> 在 oracle pl sql.is 和调用运算符中是啥意思?

PL/SQL 编程

oracle pl/sql 关于程序执行方式的问题

PL/SQL,如何在字符串中转义单引号?