2

我有一个带有子选择的查询,其中我输入了错误的列(子选择中的 id1)。如果单独执行查询,SQL Server 会抛出一个错误,这是正确的和预期的。但是,如果在以下上下文中作为子查询执行,则不会捕获错字 - 在这种情况下,我的表被清除。这是故意的行为吗?

CREATE TABLE #a1 (id1 INT);
CREATE TABLE #a2 (id2 INT);

INSERT INTO #a1 (id1) VALUES (1), (2), (3);
INSERT INTO #a2 (id2) VALUES (1);

DELETE FROM #a1 WHERE id1 = (SELECT id1 FROM #a2 WHERE id2 = 1);

SELECT * FROM #a1 -- wow, the table is now empty

我预计会抛出一个错误,而不是删除查询被解释为

DELETE FROM #a1 WHERE id1 = id1.
4

3 回答 3

2

外部查询中声明的表中的列在内部查询中可用。这与构建相关子查询时发挥作用的逻辑相同。

所以在这种情况下:

WHERE id1 = (SELECT id1 FROM #a2 WHERE id2=1)

子查询返回与 table 中一样多的记录#a2id1来自外部查询。只要有#a2满足条件的唯一记录,id2 = 1其实就相当于WHERE id1 = id1

如果你在列名前加上表别名,你会收到一个错误:

DELETE FROM #a1 t1 WHERE t1.id1 = (SELECT t2.id1 FROM #a2 t2 WHERE t2.id2 = 1);
于 2019-11-12T15:08:46.380 回答
2

是的,这是预期行为,因为您的查询明确如下所示:

DELETE FROM #a1 WHERE id1=(SELECT #a1.id1 FROM #a2 WHERE #a2.id2=1);

id1 在子查询中是已知的,因为它属于 #a1 并且因为对于每一行,您选择的值与您收到的完全相同:

delete from #a1 where id1=id1

但是仅对于子查询(即没有删除部分)- id1 未知,因此它按预期显示错误。

于 2019-11-12T15:08:31.210 回答
0

id1在表中A1

delete将查询更改为a select,您将看到。

于 2019-11-12T15:11:29.540 回答