SQL*Plus BREAK 的行为如何/为什么取决于列顺序?
How / why does behavior of SQL*Plus BREAK depend on column order?
背景
我对数据库很熟悉,但从未特别使用过 Oracle。在尝试帮助某人完成家庭作业的过程中,我在试图理解 BREAK
命令的行为时遇到了障碍。特别是,使用 BREAK
命令的结果似乎取决于我正在使用的查询中列的顺序,据我所知,这并没有以任何方式反映在文档中。
示例设置
我创建了一个 table,其中有几种不同的颜色,每种颜色都有一些该颜色的项目,如下所示:
CREATE TABLE products(product_id NUMBER, product_color VARCHAR(10), product_name VARCHAR(20));
INSERT INTO products(product_id, product_color, product_name) VALUES(1, 'Green', 'Green baseball cap');
INSERT INTO products(product_id, product_color, product_name) VALUES(2, 'Green', 'Green shirt');
INSERT INTO products(product_id, product_color, product_name) VALUES(3, 'Green', 'Grapes');
INSERT INTO products(product_id, product_color, product_name) VALUES(4, 'Orange', 'Orange baseball cap');
INSERT INTO products(product_id, product_color, product_name) VALUES(5, 'Orange', 'Traffic cone');
显示预期行为的示例
当我运行以下命令时,
CLEAR COLUMNS;
CLEAR BREAKS;
CLEAR SCREEN;
SET LINESIZE 120;
COLUMN product_color NOPRINT NEW_VALUE the_color;
BREAK ON product_color SKIP PAGE;
TTITLE CENTER the_color;
SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
这似乎产生了合理的输出,每种颜色一个“页面”在顶部显示颜色并在下方显示相关记录:
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
表现出意外行为的看似相同的示例
但是,如果我只是更改查询中列的顺序,即将上面脚本的最后一行替换为:
SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
那么结果就完全不同了,在每条记录后无缘无故地生成一个分页符:
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
2 Green shirt
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
5 Traffic cone
问题
- 为什么更改查询输出中列的顺序会导致与
BREAK
语句不同的行为? (或者 BREAK
命令是一个转移注意力的问题,第二个示例中的分页符是出于某种不相关的原因而创建的吗?)
- 这是否实际上以某种方式记录在文档中,但以某种方式我不理解?
- 是否有描述此行为的术语可供我搜索以了解更多信息?
- 有没有比官方 Oracle 站点更好的 SQL*Plus 文档?它似乎相当参差不齐,很少明确指定命令的作用。
可能的线索
我已经通读了位于 https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve009.htm#SQPUG030 的 SQL*Plus BREAK
命令的文档,但我没有看到任何与列出现顺序相关的内容。
我认为这个问题可能与抑制干扰字段更改检测的重复项有关,但是将 DUPLICATES
添加到 BREAK
命令没有任何效果。
在六种可能的排列中,看起来导致问题的是其中 product_color
是第一列的两个排列。
同样,将查询更改为
SELECT 1, product_color, product_id, product_name FROM products ORDER BY product_color;
产生了预期的行为,表明最左边的列可能在这里扮演了一些特殊的角色。
此外,我发现从 COLUMN
命令中删除 NOPRINT
可以消除这种行为,原因我不明白。
环境信息
oracle 服务器报告它是
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE 11.2.0.4.0 Production"
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
我正在使用 Oracle SQL Developer version 21.2.1.204,Build 204.1703 进行连接。
您示例中 BREAK
的行为不正确。感谢@Littlefoot,我更新了这个 post,这是因为您使用的是 SqlDeveloper,一个不适合此类报告的 java 工具。
我创建了您的 table 并将记录插入到两个数据库中,然后 运行 收集您所做的报告。
演示 12cR2
SQL> select banner from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE 12.2.0.1.0 Production
TNS for Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production
SQL> CREATE TABLE products(product_id NUMBER, product_color VARCHAR(10), product_name VARCHAR(20));
Table created.
INSERT INTO products(product_id, product_color, product_name) VALUES(1, 'Green', 'Green baseball cap');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(2, 'Green', 'Green shirt');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(3, 'Green', 'Grapes');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(4, 'Orange', 'Orange baseball cap');
1 row created.
SQL> INSERT INTO products(product_id, product_color, product_name) VALUES(5, 'Orange', 'Traffic cone');
1 row created.
现在让我们运行报告
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR breaks;
breaks cleared
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL> TTITLE CENTER the_color;
SQL> SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
如您所见,在 12.2 中,BREAK
命令没有意外行为,它可以正常工作。
演示 19c
SQL> select banner_full from v$version ;
BANNER_FULL
------------------------------------------------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.6.0.0.0
SQL> CREATE TABLE products(product_id NUMBER, product_color VARCHAR(10), product_name VARCHAR(20));
Table created.
INSERT INTO products(product_id, product_color, product_name) VALUES(1, 'Green', 'Green baseball cap');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(2, 'Green', 'Green shirt');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(3, 'Green', 'Grapes');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(4, 'Orange', 'Orange baseball cap');
1 row created.
SQL> INSERT INTO products(product_id, product_color, product_name) VALUES(5, 'Orange', 'Traffic cone');
1 row created.
现在,让我们运行报告
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR BREAKS;
breaks cleared
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL> TTITLE CENTER the_color;
SQL> SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
因此,BREAK
命令的预期行为相同。
回答您的问题
为什么更改查询输出中列的顺序会导致与 BREAK
语句不同的行为? (或者 BREAK
命令是一个转移注意力的问题,第二个示例中的分页符是出于某种不相关的原因而创建的吗?)
它不会。正如我之前所说,这种行为在 12c 和 19c 中都无法重现(如 @Littlefoot 所示,在 11g 中无法重现)。我向您保证 BREAK
的正常行为不受订单的影响。
这是否实际上以某种方式记录在文档中,但在某些方面我不理解?
不是真的,因为您了解命令的工作原理,但不了解您获得的行为,这显然无法在 12c 或更高版本中重现。我无法在 11g 中进行任何测试,因为这是一个非常旧且不受支持的版本,但在@Littlefoot 的另一个答案中,您可以看到行为是相同的。
有没有比官方 Oracle 站点更好的 SQLPlus 文档?它似乎相当参差不齐,很少明确指定命令的作用。*
参考资料是您能找到的最好的。显然,与其他所有主要软件供应商一样,Oracle 的文档编制并不完美。老实说,我不能为此责怪他们,因为它无处不在。事实上,我确实认为他们有最好的之一。
我的建议:使用 sqlplus
并升级您的数据库。 11g 多年前就被弃用了。您可以尝试使用 sqlcl
sql 开发人员命令行界面,但我从未使用过 11g,尽管我认为这应该不是问题
顺便说一句,关于 我发现从 COLUMN 命令中删除 NOPRINT 会使这种行为消失,原因我不明白。
PRINT|NOPRINT Controls the printing of the column (the column heading and all the
selected values). NOPRINT turns off the screen output and printing of
the column. PRINT turns the printing of the column ON.
不完全是。如果将 NOPRINT
更改为 PRINT
,它会正常工作,因此您可以打印属于 BREAK
的列。但是,它只在结果中显示一次,因为你打破了它。
SQL> COLUMN product_color PRINT NEW_VALUE the_color;
SQL> SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_CO PRODUCT_NAME
---------- ---------- --------------------
1 Green Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_CO PRODUCT_NAME
---------- ---------- --------------------
4 Orange Orange baseball cap
5 Traffic cone
希望这个冗长的回答能以某种方式帮助到您。随时提出您可能有的任何问题或疑问。但我很确定原因是你的版本。
更新
正如@Littlefoot 在下面的回答中所述,该问题可能与 SQLDeveloper 有关,这是一个 Java 工具。我没有意识到你在使用 SQL Developer,即使你可以 运行 脚本,但对于那些 sqlplus
特定的报告命令来说并不相同。我依赖于您指向 sqlplus
的文档链接,所以我自然假设您正在使用它。
奇怪。我的环境和你的一样,我没有看到这样的行为。我刚刚从您发布的代码中删除了 clear screen
。
这是一个 returns 为您(和我)提供正确结果的查询。
客户端 11.2.0.2.0
C:\Oracle\oraclexe112_64bit\app\oracle\product.2.0\server\bin>sqlplus scott/tiger@orcl
SQL*Plus: Release 11.2.0.2.0 Production on ╚et Stu 11 08:03:58 2021
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR BREAKS;
breaks cleared
SQL>
SQL> SET LINESIZE 120;
SQL>
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL>
SQL> TTITLE CENTER the_color;
SQL>
SQL> SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL>
现在,在您的数据库中产生意外中断的查询(但在我的数据库中没有),product_color
是 select
列列表中的第一列:
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL>
我也尝试了不同的客户端,没问题:
客户端 11.2.0.1.0
SQL*Plus: Release 11.2.0.1.0 Production on ╚et Stu 11 08:10:56 2021
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR BREAKS;
breaks cleared
SQL>
SQL> SET LINESIZE 120;
SQL>
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL>
SQL> TTITLE CENTER the_color;
SQL>
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL>
客户端 18.5.0.0.0
SQL*Plus: Release 18.0.0.0.0 - Production on Thu Nov 11 08:12:20 2021
Version 18.5.0.0.0
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR BREAKS;
breaks cleared
SQL>
SQL> SET LINESIZE 120;
SQL>
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL>
SQL> TTITLE CENTER the_color;
SQL>
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL>
我认为这很重要:
I am using Oracle SQL Developer version 21.2.1.204, Build 204.1703 to connect.
SQL 开发人员。我和罗伯托使用 SQL Plus,Oracle 的命令行工具。
当我测试你的代码时,returns 结果是“无效”,这是真的!
columns cleared
breaks cleared
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
2 Green shirt
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
5 Traffic cone
SQL 开发人员 产生了“错误”的结果。与数据库版本无关,而是工具.
那么,怎么办?请改用 SQL*Plus :) 或者,下载 Oracle 提供的最新命令行工具 SQLcl。
背景
我对数据库很熟悉,但从未特别使用过 Oracle。在尝试帮助某人完成家庭作业的过程中,我在试图理解 BREAK
命令的行为时遇到了障碍。特别是,使用 BREAK
命令的结果似乎取决于我正在使用的查询中列的顺序,据我所知,这并没有以任何方式反映在文档中。
示例设置
我创建了一个 table,其中有几种不同的颜色,每种颜色都有一些该颜色的项目,如下所示:
CREATE TABLE products(product_id NUMBER, product_color VARCHAR(10), product_name VARCHAR(20));
INSERT INTO products(product_id, product_color, product_name) VALUES(1, 'Green', 'Green baseball cap');
INSERT INTO products(product_id, product_color, product_name) VALUES(2, 'Green', 'Green shirt');
INSERT INTO products(product_id, product_color, product_name) VALUES(3, 'Green', 'Grapes');
INSERT INTO products(product_id, product_color, product_name) VALUES(4, 'Orange', 'Orange baseball cap');
INSERT INTO products(product_id, product_color, product_name) VALUES(5, 'Orange', 'Traffic cone');
显示预期行为的示例
当我运行以下命令时,
CLEAR COLUMNS;
CLEAR BREAKS;
CLEAR SCREEN;
SET LINESIZE 120;
COLUMN product_color NOPRINT NEW_VALUE the_color;
BREAK ON product_color SKIP PAGE;
TTITLE CENTER the_color;
SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
这似乎产生了合理的输出,每种颜色一个“页面”在顶部显示颜色并在下方显示相关记录:
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
表现出意外行为的看似相同的示例
但是,如果我只是更改查询中列的顺序,即将上面脚本的最后一行替换为:
SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
那么结果就完全不同了,在每条记录后无缘无故地生成一个分页符:
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
2 Green shirt
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
5 Traffic cone
问题
- 为什么更改查询输出中列的顺序会导致与
BREAK
语句不同的行为? (或者BREAK
命令是一个转移注意力的问题,第二个示例中的分页符是出于某种不相关的原因而创建的吗?) - 这是否实际上以某种方式记录在文档中,但以某种方式我不理解?
- 是否有描述此行为的术语可供我搜索以了解更多信息?
- 有没有比官方 Oracle 站点更好的 SQL*Plus 文档?它似乎相当参差不齐,很少明确指定命令的作用。
可能的线索
我已经通读了位于 https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve009.htm#SQPUG030 的 SQL*Plus BREAK
命令的文档,但我没有看到任何与列出现顺序相关的内容。
我认为这个问题可能与抑制干扰字段更改检测的重复项有关,但是将 DUPLICATES
添加到 BREAK
命令没有任何效果。
在六种可能的排列中,看起来导致问题的是其中 product_color
是第一列的两个排列。
同样,将查询更改为
SELECT 1, product_color, product_id, product_name FROM products ORDER BY product_color;
产生了预期的行为,表明最左边的列可能在这里扮演了一些特殊的角色。
此外,我发现从 COLUMN
命令中删除 NOPRINT
可以消除这种行为,原因我不明白。
环境信息
oracle 服务器报告它是
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE 11.2.0.4.0 Production"
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
我正在使用 Oracle SQL Developer version 21.2.1.204,Build 204.1703 进行连接。
您示例中 BREAK
的行为不正确。感谢@Littlefoot,我更新了这个 post,这是因为您使用的是 SqlDeveloper,一个不适合此类报告的 java 工具。
我创建了您的 table 并将记录插入到两个数据库中,然后 运行 收集您所做的报告。
演示 12cR2
SQL> select banner from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE 12.2.0.1.0 Production
TNS for Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production
SQL> CREATE TABLE products(product_id NUMBER, product_color VARCHAR(10), product_name VARCHAR(20));
Table created.
INSERT INTO products(product_id, product_color, product_name) VALUES(1, 'Green', 'Green baseball cap');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(2, 'Green', 'Green shirt');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(3, 'Green', 'Grapes');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(4, 'Orange', 'Orange baseball cap');
1 row created.
SQL> INSERT INTO products(product_id, product_color, product_name) VALUES(5, 'Orange', 'Traffic cone');
1 row created.
现在让我们运行报告
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR breaks;
breaks cleared
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL> TTITLE CENTER the_color;
SQL> SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
如您所见,在 12.2 中,BREAK
命令没有意外行为,它可以正常工作。
演示 19c
SQL> select banner_full from v$version ;
BANNER_FULL
------------------------------------------------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.6.0.0.0
SQL> CREATE TABLE products(product_id NUMBER, product_color VARCHAR(10), product_name VARCHAR(20));
Table created.
INSERT INTO products(product_id, product_color, product_name) VALUES(1, 'Green', 'Green baseball cap');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(2, 'Green', 'Green shirt');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(3, 'Green', 'Grapes');
1 row created.
INSERT INTO products(product_id, product_color, product_name) VALUES(4, 'Orange', 'Orange baseball cap');
1 row created.
SQL> INSERT INTO products(product_id, product_color, product_name) VALUES(5, 'Orange', 'Traffic cone');
1 row created.
现在,让我们运行报告
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR BREAKS;
breaks cleared
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL> TTITLE CENTER the_color;
SQL> SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
因此,BREAK
命令的预期行为相同。
回答您的问题
为什么更改查询输出中列的顺序会导致与 BREAK
语句不同的行为? (或者 BREAK
命令是一个转移注意力的问题,第二个示例中的分页符是出于某种不相关的原因而创建的吗?)
它不会。正如我之前所说,这种行为在 12c 和 19c 中都无法重现(如 @Littlefoot 所示,在 11g 中无法重现)。我向您保证 BREAK
的正常行为不受订单的影响。
这是否实际上以某种方式记录在文档中,但在某些方面我不理解?
不是真的,因为您了解命令的工作原理,但不了解您获得的行为,这显然无法在 12c 或更高版本中重现。我无法在 11g 中进行任何测试,因为这是一个非常旧且不受支持的版本,但在@Littlefoot 的另一个答案中,您可以看到行为是相同的。
有没有比官方 Oracle 站点更好的 SQLPlus 文档?它似乎相当参差不齐,很少明确指定命令的作用。*
参考资料是您能找到的最好的。显然,与其他所有主要软件供应商一样,Oracle 的文档编制并不完美。老实说,我不能为此责怪他们,因为它无处不在。事实上,我确实认为他们有最好的之一。
我的建议:使用 sqlplus
并升级您的数据库。 11g 多年前就被弃用了。您可以尝试使用 sqlcl
sql 开发人员命令行界面,但我从未使用过 11g,尽管我认为这应该不是问题
顺便说一句,关于 我发现从 COLUMN 命令中删除 NOPRINT 会使这种行为消失,原因我不明白。
PRINT|NOPRINT Controls the printing of the column (the column heading and all the selected values). NOPRINT turns off the screen output and printing of the column. PRINT turns the printing of the column ON.
不完全是。如果将 NOPRINT
更改为 PRINT
,它会正常工作,因此您可以打印属于 BREAK
的列。但是,它只在结果中显示一次,因为你打破了它。
SQL> COLUMN product_color PRINT NEW_VALUE the_color;
SQL> SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_CO PRODUCT_NAME
---------- ---------- --------------------
1 Green Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_CO PRODUCT_NAME
---------- ---------- --------------------
4 Orange Orange baseball cap
5 Traffic cone
希望这个冗长的回答能以某种方式帮助到您。随时提出您可能有的任何问题或疑问。但我很确定原因是你的版本。
更新
正如@Littlefoot 在下面的回答中所述,该问题可能与 SQLDeveloper 有关,这是一个 Java 工具。我没有意识到你在使用 SQL Developer,即使你可以 运行 脚本,但对于那些 sqlplus
特定的报告命令来说并不相同。我依赖于您指向 sqlplus
的文档链接,所以我自然假设您正在使用它。
奇怪。我的环境和你的一样,我没有看到这样的行为。我刚刚从您发布的代码中删除了 clear screen
。
这是一个 returns 为您(和我)提供正确结果的查询。
客户端 11.2.0.2.0
C:\Oracle\oraclexe112_64bit\app\oracle\product.2.0\server\bin>sqlplus scott/tiger@orcl
SQL*Plus: Release 11.2.0.2.0 Production on ╚et Stu 11 08:03:58 2021
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR BREAKS;
breaks cleared
SQL>
SQL> SET LINESIZE 120;
SQL>
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL>
SQL> TTITLE CENTER the_color;
SQL>
SQL> SELECT product_id, product_color, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL>
现在,在您的数据库中产生意外中断的查询(但在我的数据库中没有),product_color
是 select
列列表中的第一列:
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL>
我也尝试了不同的客户端,没问题:
客户端 11.2.0.1.0
SQL*Plus: Release 11.2.0.1.0 Production on ╚et Stu 11 08:10:56 2021
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR BREAKS;
breaks cleared
SQL>
SQL> SET LINESIZE 120;
SQL>
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL>
SQL> TTITLE CENTER the_color;
SQL>
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL>
客户端 18.5.0.0.0
SQL*Plus: Release 18.0.0.0.0 - Production on Thu Nov 11 08:12:20 2021
Version 18.5.0.0.0
SQL> CLEAR COLUMNS;
columns cleared
SQL> CLEAR BREAKS;
breaks cleared
SQL>
SQL> SET LINESIZE 120;
SQL>
SQL> COLUMN product_color NOPRINT NEW_VALUE the_color;
SQL> BREAK ON product_color SKIP PAGE;
SQL>
SQL> TTITLE CENTER the_color;
SQL>
SQL> SELECT product_color, product_id, product_name FROM products ORDER BY product_color;
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
2 Green shirt
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
5 Traffic cone
SQL>
我认为这很重要:
I am using Oracle SQL Developer version 21.2.1.204, Build 204.1703 to connect.
SQL 开发人员。我和罗伯托使用 SQL Plus,Oracle 的命令行工具。
当我测试你的代码时,returns 结果是“无效”,这是真的!
columns cleared
breaks cleared
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
1 Green baseball cap
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
2 Green shirt
Green
PRODUCT_ID PRODUCT_NAME
---------- --------------------
3 Grapes
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
4 Orange baseball cap
Orange
PRODUCT_ID PRODUCT_NAME
---------- --------------------
5 Traffic cone
SQL 开发人员 产生了“错误”的结果。与数据库版本无关,而是工具.
那么,怎么办?请改用 SQL*Plus :) 或者,下载 Oracle 提供的最新命令行工具 SQLcl。