FROM 子句中的嵌套括号是有效的 Oracle SQL 语法



此查询是否使用正确的 Oracle 语法?

select * from ( ( ( dual a) ) ) where a.dummy = 'X';

它适用于 11g 和 12c,但它真的有效吗? 或者这只是一个编译器"错误",将来可能会修复,导致代码失败?

我怀疑这是正确的语法,原因如下:

  1. 除了添加额外的括号之外,它似乎没有做任何事情。 像 ((1+2(*3( 这样的表达式显然可以从嵌套括号中受益,但我看不出它们如何帮助 FROM 子句。 当我查看上面的查询时,别名"a"看起来超出了范围。
  2. 我在 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;

括号允许您对表进行内部联接 bc,然后将其外联接到 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 JOINLEFT 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 JOINRIGHT OUTER JOINFULL 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)));

相关内容

  • 没有找到相关文章

最新更新