首页 > 解决方案 > 为什么引用不属于正在查询的表的列(作为左侧操作数)不是 EXISTS 运算符中的错误?

问题描述

鉴于此 SQL 批处理:

CREATE TABLE #source
(
  ID int,
  SourceDescr varchar(255)
)
INSERT INTO #source
VALUES
(1, 'first'),
(2, 'second')


CREATE TABLE #target
(
  ID int,
  TargetDescr varchar(255)
)
INSERT INTO #target
SELECT * FROM #source

INSERT INTO #target
SELECT * FROM #source S
WHERE NOT EXISTS
(
  SELECT 1
  FROM #target
  WHERE SourceDescr = S.SourceDescr
  --       /\ How is this not an error?
)

为什么运算符中的WHERE子句EXISTS起作用?表中肯定没有SourceDescr#target

我什至试过这个,它也有效:

INSERT INTO #target
SELECT * FROM #source S
WHERE NOT EXISTS
(
  SELECT SourceDescr -- ??
  FROM #target
  WHERE SourceDescr = S.SourceDescr
)

阅读EXISTS的官方文档并没有为我澄清这一点。

谢谢。

标签: sqlsql-servertsqlsql-server-2008exists

解决方案


这被解释为:

INSERT INTO #target
    SELECT S.*
    FROM #source S
    WHERE NOT EXISTS
    (
      SELECT 1
      FROM #target
      WHERE S.SourceDescr = S.SourceDescr
    );

它运行,但它并没有按照您的意图进行。

这就是为什么我建议在所有查询中为所有列引用使用限定列名的原因之一。您的预期逻辑:

INSERT INTO #target
    SELECT S.*
    FROM #source S
    WHERE NOT EXISTS
    (
      SELECT 1
      FROM #target t
      WHERE t.SourceDescr = S.SourceDescr
    );

会产生编译时错误并且永远不会执行。


推荐阅读