如果内部 SELECT 包含无效标识符,则强制外部 SELECT 失败

Posted

技术标签:

【中文标题】如果内部 SELECT 包含无效标识符,则强制外部 SELECT 失败【英文标题】:Force outer SELECT to fail if the inner SELECT contains an invalid identifier 【发布时间】:2016-01-13 18:23:40 【问题描述】:

如果

SELECT ID FROM T2

失败并显示以下消息:

错误:ORA-00904:“ID”:无效标识符

为什么没有

SELECT * 
    FROM T1
    WHERE ID IN 
        ( 
            SELECT ID FROM T2
        )

失败? (它返回来自 T1 的所有条目)

是否可以更改此默认行为? (运行相同的查询,但得到一个错误而不是所有行)


我有:

以 ID 为列的 T1 T2 以 ID2 作为列(T2 不包含 ID)

但是假设我错误地使用了SELECT ID FROM T2(参见上面的示例)而不是SELECT ID2 FROM T2。在这种情况下没有任何问题发生,因为我使用SELECT ... IN SELECT ...,但如果将其替换为DELETE ... IN SELECT ...,它可能会产生重大损害。

【问题讨论】:

【参考方案1】:

行为解释in this question。

但您也问:“是否可以更改此默认行为? (运行相同的查询,但得到一个错误而不是所有行)”并在评论中扩展了“我想强制相同查询失败,而不是更改查询以获得想要的结果”。

不,无法更改行为。它正在做the documentation 说它应该做的事情:

Oracle 通过查看子查询中命名的表,然后查看父语句中命名的表来解析子查询中的不合格列。

您不能让它停止查看父语句而只解析子查询中的非限定别名。您必须更改查询以使其出错。没有理由限定您的标识符,并且有很多理由应该这样做,包括它可以防止您掩盖代码中的错误。

【讨论】:

好的,我了解别名的重要性。因为我似乎无法阻止这种情况,所以我希望任何可以在同一个数据库上运行查询的人都不会使用没有别名的DELETE ... WHERE ... IN SELECT ... @engineer - 您的编码标准可能会坚持使用它们,并且您的代码审查过程可能会发现它们丢失并且已经犯了这样的错误......无论如何,这是理想的*8 -) 我不希望任何人在没有充分理由的情况下运行临时删除,即使那样他们也应该小心。是的,也是理想...【参考方案2】:

是的。

SELECT * 
    FROM T1
    WHERE ID IN 
        ( 
            SELECT T2.ID FROM T2
        )

【讨论】:

我编辑了我的帖子。我想强制相同查询失败,而不是更改查询以获得想要的结果。 这回答了这个问题。如果您不想收到错误,请始终限定您的列名。 @GordonLinoff ,不知道大家是否熟悉Hibernate(或者其他ORM),打个比方……如果默认抓取策略是惰性的,那我可以改成渴望的。我不修改代码(查询),但我给 Hibernate 一些指令来改变它的默认行为。 我对你的问题投了赞成票,因为它回答了标题中的问题并且对其他人非常有用,但我接受了另一个答案,因为它更关注我在编辑中提供的细节。跨度> 很公平。我也赞成亚历克斯的回答。这是最好的。

以上是关于如果内部 SELECT 包含无效标识符,则强制外部 SELECT 失败的主要内容,如果未能解决你的问题,请参考以下文章

php中在循环外部如何强制结束循环?

[JavaScript语法学习]全面介绍函数

ORA-00904: 子查询中的无效标识符(在选择子句中)

如果在 Select-Query 中满足特定条件,则创建唯一标识符

例外:oauth 状态丢失或无效。 (ASP.NET Core 外部标识符 OAuth)

mysql - 如何强制更改内部连接的评估顺序?