为什么此SQL代码表现出这个原因。编译错误不应该抛出吗?

时间:2019-05-14 11:11:17

标签: sql sql-server

检查此SQL问题。 SQL为何编译非常有趣。最后一个选择语句应该抛出错误,因为临时表中不存在client_id列。似乎正在使用第一个表client_orders的范围。但是即使如此,一旦解析,它在评估IN语句时也始终解析为TRUE。下面是一些代码。

这只是一个难题。我有一个资源管理器,当IN中的语句为null或无效,并且只是将其作为编译错误时,会发生什么情况。似乎对使用client_id感到困惑。

这里是例子。

IF OBJECT_ID('client_order') IS NOT NULL DROP TABLE client_order
IF OBJECT_ID('tempdb.dbo.#to_delete') IS NOT NULL DROP TABLE #to_delete
GO

CREATE TABLE client_order
(
       client_id INT NOT NULL,
       order_id INT NOT NULL,
       order_data CHAR(100) NOT NULL DEFAULT '{"amount":12}'
)
GO

INSERT INTO client_order (client_id, order_id) VALUES
(1, 1),
(1, 2),
(2, 1),
(2, 2),
(2, 3),
(3, 1)

SELECT * FROM client_order

CREATE TABLE #to_delete
(
       bobo INT NOT NULL
)

INSERT INTO #to_delete VALUES (1),(3)

SELECT * FROM client_order
WHERE client_id IN (SELECT client_id FROM #to_delete)
  • WTF?为什么所有记录都被退回?!
  • 我知道#to_delete中的select使用了不正确的列,但是为什么没有将其捕获为错误
  • 此外,当检查client_id是否在该语句中时,为什么选择语句总是返回true?

client_id值2仍应保留。他们为什么不呢?

1 个答案:

答案 0 :(得分:8)

您的表#to_delete没有名为client_id的列。所以,您认为您已经写了:

SELECT co.*
FROM client_order co
WHERE co.client_id IN (SELECT d.client_id FROM #to_delete d);

但是这将产生列未知错误。因此,这被解释为:

SELECT co.*
FROM client_order co
WHERE co.client_id IN (SELECT co.client_id FROM #to_delete d);

一切都会返回。

课程:始终限定查询中的所有列引用。如果在表名中包含表别名,则永远不会出现此问题。