此查询是否使用正确的 Oracle 语法?
select * from ( ( ( dual a) ) ) where a.dummy = 'X';
它适用于 11g 和 12c,但它真的有效吗? 或者这只是一个编译器"错误",将来可能会修复,导致代码失败?
我怀疑这是正确的语法,原因如下:
- 除了添加额外的括号之外,它似乎没有做任何事情。 像 ((1+2(*3( 这样的表达式显然可以从嵌套括号中受益,但我看不出它们如何帮助 FROM 子句。 当我查看上面的查询时,别名"a"看起来超出了范围。
- 我在 SQL 语言参考语法图中找不到此语法的有效路径。 另一方面,很容易看出表达式、条件、和子查询。 表达式、条件和子查询是递归的,可以包含括号,但连接子句不是递归的。
我担心这一点,因为也有类似的情况,无效语法在一个版本中工作,然后在下一个版本中失败。 例如:select (select count(*) from (select * from scott.emp where ename = dual.dummy)) from dual;
. 该查询在 10.2.0.1.0 中有效,但在更高版本中停止工作,因为表引用的范围仅限于一个级别深度。
原始查询的风格很糟糕,但除非存在真正的问题,否则不值得更改我们的生产查询。
查询无效吗? 或者该语法是否有一些合法的原因,或者语法图中是否缺少一些路径?
FROM
的连接子句中使用括号是合法的语法,括号确实有效果。
请考虑以下查询:
WITH table_a AS ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 30),
table_b as ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 20),
table_c AS ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 10)
SELECT a.id, b.id, c.id
FROM table_a a left join ( table_b b inner join table_c c ON c.id = b.id ) ON b.id = a.id
ORDER BY 1,2,3;
括号允许您对表进行内部联接 b
和 c
,然后将其外联接到 a
。
如果没有括号,试图将其表达为左连接是不可能的。 您要么不会从表 a
中获取第 11-30 行,要么表 c
的第 11-20 行将null
s(取决于您尝试执行此操作的方式(。
请注意,上述查询等效于:
WITH table_a AS ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 30),
table_b as ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 20),
table_c AS ( SELECT rownum id FROM DUAL CONNECT BY LEVEL <= 10)
SELECT a.id, b.id, c.id
FROM table_b b inner join table_c c on c.id = b.id right join table_a a on a.id = b.id
ORDER BY 1,2,3;
,不需要括号。 因此,如果您真的想避免在FROM
子句中使用括号,通常可以这样做。 就个人而言,我更喜欢带括号而不是RIGHT JOIN
的LEFT JOIN
方法.
根据我对 SELECT 语句语法图的阅读,不允许在 SELECT 语句中的表引用周围加上括号。至于甲骨文是否会以一种使其无效的方式"修复"事情,我无法知道,但我认为不太可能。扬子晚报.
祝你好运。
编辑
只是为了好玩,我想我会放下对语法图的阅读:
正如其他人所指出的,括号允许在join_clause
周围,但dual a
不是join_clause
。相反,它是一个query_table_expression
,是table_reference
的一部分。 dual a
不能是join_clause
——要成为这样,它后面必须跟着一个inner_join_clause
(例如 INNER JOIN
( 或outer_join_clause
(例如 LEFT OUTER JOIN
、RIGHT OUTER JOIN
或 FULL OUTER JOIN
(,但事实并非如此。根据语法图,除非query_table_expression
前面有ONLY
,否则不允许在query_table_expression
周围使用括号,而在OP的查询中,dual a
前面没有ONLY
。因此,我得出结论,根据 Oracle 语法图( ( (dual a) ) )
语法不正确;但是,数据库似乎不同意。:-)
除了join_clause之外,子查询可以是嵌套的。
所以这是完美的有效语法
(((select * from dual)));
这为被质疑查询的 synax 的有效性提供了线索。
select * from (((dual)));
从选择开始,我们转到query_block
select --> subquery --> query_block
query_block
扩展到
SELECT * FROM table_reference
从table_reference
我们下降到(嵌套(subquery
,可以进一步嵌套。
table_reference --> query_table_expression --> ( subquery )
因此,请继续扩展subquery
以获得所需的嵌套和最终选择TABLE
作为query_table_expression的扩展
但正如MT0和其他人所指出的,不幸的是,这并没有导致e3xpected结果。最大法律查询为
select * from (((select * from dual)));