【问题标题】:Delete rows in two table based on conditions in two different tables根据两个不同表中的条件删除两个表中的行
【发布时间】:2026-01-13 00:20:03
【问题描述】:

长时间观看,第一次提问

我目前正在做一些事情,我必须根据两个不同表上的条件删除两个表上的数据。我只是 SQL 的初学者,这已经困扰了我一上午。

这两个条件是客户表中的GDPR已设置为N,以及支付交易表中的支付日期大于30天

create proc MemberDelete

delete from ClientsPersonalInfo
from Clients, PaymentTransaction
where ClientsPersonalInfo.ClientID = Clients.ClientID and Clients.GDPR = 'N' and (select datediff(dd,PaymentDate,GETDATE()) from PaymentTransaction)>30

delete from GymCard
from Clients, PaymentTransaction
where GymCard.ClientID = Clients.ClientID and Clients.GDPR = 'N' and (select datediff(dd,PaymentDate,GETDATE()) from PaymentTransaction)>30

If @@rowcount <>1
rollback

else 
Commit

真的不知道我在哪里做错了吗?我得到的错误是以下“子查询返回超过 1 个值。当子查询遵循 =、!=、、>= 或将子查询用作表达式时,这是不允许的。”

Proc 的重点是如果 ClientPersonalInfo 和 GymCard 的 ClientID 符合 Clients 和 PaymentTransaction 表中的两个条件,则硬删除数据。这是因为客户没有勾选 GDPR 框以便我们保留信息,并且他们的最后付款日期超过 30 天。

【问题讨论】:

  • “真的不知道我在哪里做错了?” 那你有什么问题?你不告诉我们。此外,您停止使用古老的 JOIN 语法已经 long 了。 ANSI-92 JOIN 语法已经存在将近 30 年了。
  • 样本数据和期望的结果会有所帮助。对您想要做什么的描述也很有帮助。
  • 抱歉,我应该详细说明。尝试执行时出现以下错误。 “子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。”。我想要做的是,如果 ClientID 符合 PaymentTransaction 和 Clients 表中的两个条件,我想删除它们在 ClientsPersonalInfo 和 GymCard 表中的所有数据。
  • Clients 和 PaymentTransaction 是什么关系?这也是ClientID吗?
  • 不要尝试提交您的程序未开始的事务。启动事务的过程应该(并且可能假设它有)该责任,并依靠该责任来完成(可能)更复杂的过程,您的过程是其中的一部分。如果那不是您的设计,请修复它。

标签: sql-server tsql stored-procedures


【解决方案1】:

您必须使用 ClientID 加入 PaymentTransaction。

您还需要通过 PaymentTransaction 加入 GymCard。

create proc MemberDelete

delete from ClientsPersonalInfo
from Clients, PaymentTransaction
where 
  ClientsPersonalInfo.ClientID = PaymentTransaction.ClientID and
  ClientsPersonalInfo.ClientID = Clients.ClientID and
  Clients.GDPR = 'N' and (select datediff(dd,PaymentDate,GETDATE())
                          from PaymentTransaction
                          where
                            ClientsPersonalInfo.ClientID = PaymentTransaction.ClientID)>30

delete from GymCard
from Clients, PaymentTransaction
where 
  GymCard.ClientID = Clients.ClientID and
  GymCard.ClientID = PaymentTransaction.ClientID and
  Clients.GDPR = 'N' and (select datediff(dd,PaymentDate,GETDATE())
                          from PaymentTransaction
                          where
                            GymCard.ClientID = PaymentTransaction.ClientID)>30

If @@rowcount <>1
rollback

else 
Commit

【讨论】:

  • 这个答案肯定是在正确的轨道上,但我想指出一些事情。我认为没有“Begin Tran”就不能回滚或提交事务。此外,@@rowcount 变量只会为您提供仅与最新语句相关的行数。