sql server 2008 management studio未检查我的查询的语法

sql server 2008 management studio未检查我的查询的语法,sql,sql-server,sql-server-2008,ssms,Sql,Sql Server,Sql Server 2008,Ssms,和往常一样,我的惊喜会有一个合理的解释,但在那之前 我有这个疑问 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 用鼠标分别选择

和往常一样,我的惊喜会有一个合理的解释,但在那之前

我有这个疑问

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子句中使用它时,它不会

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

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

如果查询在其选择列表中不投影所选表中的任何列,这是完全有效的

比如说

select 10 from HotelSupplier where id = 142
将返回一个结果集,其中包含与where子句匹配的行数,所有行的值为10

非限定列引用是从最接近的范围向外解析的,因此这只是被视为一个相关的子查询

此查询的结果将删除照片中hs_id不为null的所有行,只要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

顺便说一句,这是我个人在MicrosoftConnect上看到的最常见的错误报告。Erland Sommarskog将其包含在他的设置中,用于对表进行严格的检查,这是保持表之间列名一致的有力论据。正如@Martin所说,当内部查询中没有匹配项时,SQL语法允许从外部查询解析列名。在编写相关子查询时,这是一个福音,但有时可能会让您绊倒,因为这里

+1—只是想在您的示例中明确指出一个好的实践—包括整个查询中两部分标识符的每一列的表名。一般来说,良好的实践,删除语句的宝贵实践!谢谢,我不知道。但奇怪的是,在你的简化版本中,现有的“select Photo.hs_id”也没有生成error@Michel-它不是不存在的。它被视为一个相关的子查询,并使用从外部查询传入的值对每一行进行计算。是的,绝对同意,这个数据库中的一致性还很遥远。textkey、textid、text_key、text_id、hsid、hs_id等。当然,如果您键入了一个完全没有正确名称的错误表名,那么这对您没有帮助