【问题标题】:sql server 2008 management studio not checking the syntax of my querysql server 2008 管理工作室没有检查我的查询的语法
【发布时间】:2015-09-21 00:03:22
【问题描述】:

一如既往,我的惊讶会有一个合理的解释,但在那之前......

我有这个问题

delete from Photo  where hs_id  in (select hs_id  from HotelSupplier where id = 142)

执行得很好(后来我发现整个照片表都是空的)

但奇怪的是:HotelSupplier中没有hs_id字段,它叫hs_key

所以当我执行最后一部分时

select hs_id  from HotelSupplier where id = 142

单独(用鼠标选择查询的那部分并按 F5),我得到一个错误,但是当我在 in 子句中使用它时,它没有!

我想知道这是否是正常行为?

【问题讨论】:

    标签: sql sql-server sql-server-2008 ssms


    【解决方案1】:

    它从外部查询中获取hs_id 的值。

    在其select 列表中不投影所选表中的任何列的查询是完全有效的。

    例如

    select 10 from HotelSupplier where id = 142
    

    将返回一个结果集,其中包含与 where 子句匹配的行数以及所有行的值 10

    不合格的列引用从最近的范围向外解析,因此这只是被视为相关的子查询。

    此查询的结果将是删除 Photo 中的所有行,其中 hs_id 不为空,只要 HotelSupplier 至少有一行 id = 142(因此子查询返回至少一行)

    如果你考虑一下这样做的效果可能会更清楚一点

    delete from Photo  where Photo.hs_id  in (select Photo.hs_id)
    

    这当然等价于

    delete from Photo where Photo.hs_id = Photo.hs_id
    

    顺便说一句,这是我个人看到的 Microsoft Connect 上错误报告的最常见的“错误”。 Erland Sommarskog 将其包含在他的 wishlist for SET STRICT_CHECKS ON

    【讨论】:

    • +1 - 只是想在您的示例中明确指出一个好的做法 - 包括整个查询中每个列的表名(两部分标识符)。一般的良好实践,删除语句中的宝贵实践!
    • 谢谢,我不知道。恕我直言,这很奇怪,(在您的简化版本中)不存在的“select Photo.hs_id”不会产生错误
    • @Michel - 它并非不存在。它被视为相关子查询,并使用从外部查询传入的值对每一行进行评估。
    【解决方案2】:

    这是保持表之间列名一致的有力论据。正如@Martin 所说,当内部查询中没有匹配项时,SQL 语法允许从外部查询中解析列名。这在编写相关子查询时是一个福音,但有时会让你绊倒(就像这里一样)

    【讨论】:

    • 是的,完全同意,这个数据库的一致性还很遥远。 textkey, textid, text_key, text_id, hsid, hs_id 等等。brrrrr
    • 当然,如果你输入了错误的表名,那也无济于事
    猜你喜欢
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多