首页 > 解决方案 > 如何将 DELETE 与 EXCEPT 子句一起使用?

问题描述

我正在尝试从一些单租户数据库(每个客户端)到多租户数据库(所有客户端,或“全局”)进行一些 ETL。在全局数据库中,我试图维护一个查找表,用于标识与客户端关联的用户。所以我有这个:

Database: Global
Tables: Users and ClientUsers

Database: Client
Tables: Users

在其他一些 ETL 操作之后,我想通过删除 Client.Users 表中不再存在的任何用户来清理 ClientUsers 表。我认为这会起作用:

DECLARE @ClientID varchar = 'ClientA'

DELETE FROM Global.dto.ClientUsers
SELECT ClientID, UserID FROM Global.dto.ClientUsers WHERE ClientID=@ClientID
EXCEPT
SELECT ClientID=@ClientID, UserID FROM ClientA_DB.dbo.Users

但这会删除所有记录。我测试了各个 select 语句,它们返回了我对第一次测试的期望,没有可删除的语句。两个 select 语句都返回完全相同的数据集。这对我来说意味着不应该删除任何记录。正确的?显然,对于 EXISTS 的工作原理,我缺少一些基本的理解或细微差别,因为这看起来应该很简单!

我意识到使用其他方法可以做到这一点,但我很困惑为什么 EXCEPT 不能像我认为的那样工作。

标签: sqlsql-serversql-server-2012

解决方案


它不起作用的原因是您实际上是按顺序运行两个语句。想想你的代码更像:

DECLARE @ClientID varchar = 'ClientA'

DELETE FROM Global.dto.ClientUsers;

SELECT ClientID, UserID FROM Global.dto.ClientUsers WHERE ClientID=@ClientID
EXCEPT
SELECT ClientID=@ClientID, UserID FROM ClientA_DB.dbo.Users;

如果要修改Delete语句,则需要在其后加上Where,Join等。

有关获得所需结果的一些替代方法,请参阅以下优秀答案: 使用 T-SQL EXCEPT with DELETE / Optimizing a query


推荐阅读