首页 > 解决方案 > 为什么 SQL Server 没有捕捉到这一点?子查询中的拼写错误导致意外删除

问题描述

我有一个带有子选择的查询,其中我输入了错误的列(子选择中的 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.

标签: sql-serversubquerycolumn-alias

解决方案


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

所以在这种情况下:

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);

推荐阅读