【问题标题】:Getting Record Value while Looping through a Temporary Table在遍历临时表时获取记录值
【发布时间】:2017-02-04 07:54:13
【问题描述】:

场景

  1. 从一个 TableA 中选择记录
  2. 循环遍历表值
  3. 根据每条记录的值从另一个表(TableB)中删除

示例

DECLARE @CustomerList TABLE (CustomerID bigint) 
INSERT INTO @CustomerList SELECT CustomerID FROM TableA WHERE CustomerID = @ParameterID

WHILE (SELECT COUNT(*) FROM @CustomerList) > 0
BEGIN
DELETE FROM [TableB]
WHERE [CustomerID] = @CustomerList.CustomerID -- challenge
END

挑战

  • 传递每个循环的 CustomerID 值

更新

  • 想使用循环的原因是要执行多个删除语句

【问题讨论】:

  • 运行多次删除不是使用循环的正当理由。如果您需要多次删除,只需编写多次删除的代码。这样做是一个循环是完全错误的方法。
  • @SeanLange,你能检查一下约翰的答案吗……至少从编码背景与 sql 的角度来看,它在我看来在逻辑上是正确的。为每个删除语句重复相同的选择语句听起来效率低下。
  • 我会使用连接,但无论哪种方式都比使用循环更高效!!!
  • @SeanLange,我同意......他甚至没有使用我刚刚意识到的循环

标签: sql sql-server tsql


【解决方案1】:

为什么要循环?

Delete From [Table B]
 Where [CustomerID] in (Select CustomerID from TableA where SomeCondition=true)

好的,那么支持多次删除。你可以保持你的表变量

DECLARE @CustomerList TABLE (CustomerID bigint) 
INSERT INTO @CustomerList SELECT CustomerID FROM TableA WHERE CustomerID = @ParameterID

Delete From [Table B] Where [CustomerID] in (Select CustomerID from @CustomerList)
Delete From [Table C] Where [CustomerID] in (Select CustomerID from @CustomerList)

【讨论】:

  • 原因是实际上有多个delete语句...我更新了答案。现在我不确定使用这种技术是否仍然是最有效的方法,因为我将不得不多次调用 select 语句
  • 我可能会使用连接,但无论哪种方式,这都比循环更有效!!!
【解决方案2】:

为什么不能使用 join 而不是 while。如下所示。

DELETE t
FROM TableB as t
join @CustomerList as c
on t.CustomerID = C.CustomerID;

【讨论】:

    【解决方案3】:

    我不确定您为什么需要临时表或循环。加入应该可以工作。

    例子:

    DELETE B
    FROM TableB B
    INNER JOIN TableA A
      ON B.CustomerID=A.CustomerID
    WHERE A.CustomerID = @ParameterID
    

    【讨论】:

    • 更新了为什么循环的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多