我从开发者那里找到了这个查询:
at asset.pipeline.AssetPipelineGrailsPlugin$_doWithSpring_closure1.doCall(AssetPipelineGrailsPlugin.groovy:104)
此查询删除表 MYSIGN 。
中的所有记录字段USERID在表 MYUSER 中不存在。如果我只运行子查询:
DELETE FROM [MYDB].[dbo].[MYSIGN] where USERID in
(select USERID from [MYDB].[dbo].[MYUSER] where Surname = 'Rossi');
它会抛出正确的错误,因为缺少了列。
我们使用正确的列更正了查询,但我们没有弄明白:
规范:数据库位于SQL SERVER 2016 SP1,CU3上。
答案 0 :(得分:6)
显然你在<%= social_share_button_tag(raw("<b>#{job.title}</b>").html_safe, :url => "google.com" ) %>
中有USERID
所以它正是sql-server在[MYDB].[dbo].[MYSIGN]
中解析未加前缀的USERID
- 它将其解析为(select USERID from [MYDB].[dbo].[MYUSER] where Surname = 'Rossi')
}
使用别名,它将失败
[MYDB].[dbo].[MYSIGN].USERID
它被称为&#34;意外相关的子查询&#34;正如@NenadZivkovic所说,我喜欢这个词。
答案 1 :(得分:1)
问题是子查询的范围规则。如果在子查询表中找不到该列,则SQL引擎开始查看下一级别 - 依此类推(在SQL Server的情况下)。
每当查询中有多个表时,始终限定列名。这意味着,将表名(或别名)与列别名放在一起。那你没有歧义:
DELETE
FROM [MYDB].[dbo].[MYSIGN] m
WHERE m.USERID IN (SELECT u.USERID FROM [MYDB].[dbo].[MYUSER] u WHERE u.Surname = 'Rossi');
遵循一条简单的规则可以使您的代码更具可读性并且不易出错。