【问题标题】:Double loop with drop table in MSSQLMSSQL中带有删除表的双循环
【发布时间】:2017-03-13 14:37:21
【问题描述】:

我在 while 循环中有一个 while 循环,两个循环都对一个表进行了一些修改。我收到一个表已经存在的错误。下面这个问题的简单例子。有人可以澄清为什么这不起作用吗?我知道在这种特殊情况下如何绕过这个问题,但我想知道它是从哪里来的。

CREATE TABLE #a(
  ID int)

DECLARE @i INT
DECLARE @j INT  

SET @i = 1
SET @j = 1

WHILE @i < 10
BEGIN

    SELECT  *
    INTO #b
    FROM  #a

    DROP TABLE #b

    WHILE @j < 10 BEGIN
        SELECT  *
        INTO #b
        FROM  #a

        DROP TABLE #b

        SET @j = @j + 1
    END

  SET @i = @i + 1
END

【问题讨论】:

  • 这是一个编译错误,因为引擎没有在逻辑上处理整个批次。它看到您多次使用 select into #b 并确定这将失败。但是你很幸运,因为在 sql 中这样循环是一个非常糟糕的主意。除了极少数例外,我们可以使用基于集合的解决方案,这些解决方案比循环更易于编码、更易于维护且性能更好。
  • 问题是你只能使用 select into #b 一次。解决截断表或有 1 个为 #b 创建表和 2 个插入语句到 #b

标签: sql sql-server loops drop-table


【解决方案1】:

正如 Sean Lange 所指出的,您可以在没有循环的情况下做任何事情。

您不能在同一过程中使用两条语句来创建同名的临时表。 这是 SQL 6.5 的遗留问题,没有延迟名称解析。

不要使用select into,而是使用create table + insert

不要删除并重新创建具有相同架构的同一个表,而是使用truncate table

Answer by Erland Sommarskog on MSDN Social

create table #a(ID int);
create table #b(ID int);
declare @i int;
declare @j int;
set @i = 1;
set @j = 1;
while @i < 10
  begin;
    insert into #b (id)
      select id
      from #a;

    truncate table #b;

    while @j < 10
      begin;
        insert into #b (id)
          select id
          from #a

        truncate table #b;

        set @j = @j + 1;
      end;
    set @i = @i + 1;
  end;

【讨论】:

    猜你喜欢
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 1970-01-01
    相关资源
    最近更新 更多