2012-08-01 115 views
1

这个查询应该是从SQL数据库中删除临时表/视图,但是当删除最后一个表/视图时,它会保持循环。任何人都有答案,为什么当删除最后一个表时,这将会陷入无限循环?虽然循环问题

DECLARE @name VARCHAR(128) 

DECLARE @SQL VARCHAR(254) 

DECLARE @type VARCHAR(50) 

DECLARE @tmp_table TABLE 
    (
     table_name VARCHAR(50) 
    , table_type VARCHAR(50) 
    ) 

;WITH cte_tempTables 

      AS (
       SELECT 
       table_name 
       , crdate 
       , crdate + 90 [ExperiationDate] 
       , TABLE_TYPE 
       FROM 
       INFORMATION_SCHEMA.TABLES t 
       inner join sysobjects s 
       on s.name = t.table_name 
       WHERE 
       TABLE_CATALOG = 'SBR_Temp' 
       AND t.table_name NOT IN ('DaleDelq' ,'tblCancelContract' , 
              'tblCreateContracts' ,'MWFRTPay') 

      ) 

    INSERT INTO 
     @tmp_table 
     (
      table_name 
     , table_type 
     ) 
     select 
      table_name 
      , table_type 

     FROM 
      [cte_tempTables] 
     WHERE 
      ExperiationDate < GETDATE() 

SELECT TOP 1 
    @name = [table_name] 
    , @type = CASE WHEN [table_type] = 'BASE TABLE' THEN 'TABLE' 
       ELSE 'VIEW' 
      END 

FROM 
    @tmp_table 

WHILE @name IS NOT NULL 

    OR @name <> '' 

    BEGIN 
     SELECT 
      @SQL = 'DROP ' + @type + ' SBR_Temp.[dbo].[' + RTRIM(@name) + ']' 
      --EXEC (@SQL) 
     PRINT 'Dropped ' + @type + ':' + @name 

     DELETE 
      @tmp_table 
     WHERE 
      [table_name] = @name 

     SELECT TOP 1 
      @name = [table_name] 
      , @type = CASE WHEN [table_type] = 'BASE TABLE' THEN 'TABLE' 
         ELSE 'VIEW' 
        END 
     FROM 
      @tmp_table 
      SELECT @name 
    END 
GO 

这里是结果

(4行(一个或多个)受影响) 掉落视图的一个实例:(受影响)1行(多个)vue_SunsetCoveClientInventory

(1行(s)affected) 已删除VIEW:vue_SunsetCoveClientCoOwners

(1 row(s)affected)

(1行(一个或多个)受影响) 掉落表:(受影响1行(S))BKDischarge

(受影响1行(S))

掉落VIEW:vue_nocoop

( 1行(一个或多个)受影响)

(1行(一个或多个)受影响) 掉落VIEW:vue_nocoop

(0行(或多个)受影响)

(1行(一个或多个)受影响) 掉落VIEW:(受影响1行(S))vue_nocoop

(影响0行(S))

掉落VIEW:vue_nocoop

(0行(或多个)受影响)

(1行(一个或多个)受影响) 掉落VIEW:vue_nocoop

(0行(多个)AFF影响vue_nocoop

(0行(S))

+1

也许'@ name'是保持其原来的值,而不是设置为'NULL'或'“”'时,所有的临时表都不见了? – JAB 2012-08-01 18:27:09

回答

2

一旦你@tmp_table有没有更多的行,就不再改变:影响ected)

(1行(S)) 掉落VIEW值为@name。我想你宁愿使用:

WHILE EXISTS (SELECT NULL FROM @tmp_table) 
BEGIN 
    SELECT TOP 1... 

改变这种风格的检查也有益处:

  • 您不再假设你至少有一个排开始。
  • 您不必在两个地方维护相同的SELECT TOP 1...

你可以运行该演示代码,看看您的问题以简单的形式:

-- Setup two rows of example data 
declare @table table (
    id int primary key 
) 
insert into @table select 1 
insert into @table select 2 

declare @id int 

-- Select, display and delete the first row 
select top 1 @id = id from @table 
select @id 
delete from @table where id = @id 

-- Select, display and delete the second row 
select top 1 @id = id from @table 
select @id 
delete from @table where id = @id 

-- Nothing left to select, but @id still retains its value! 
select top 1 @id = id from @table 
select @id 
+0

WHILE EXIST有效,但必须稍微改变SELECT。最终的解决方案是WHILE EXISTS(SELECT TOP 1 [table_name] FROM @tmp_table) – 2012-08-02 13:22:26

+0

非常感谢您输入Tim ...真的很有帮助 – 2012-08-02 13:22:51

+0

很高兴帮助!不过,我很想知道是否需要更改'EXISTS'子查询。 – 2012-08-02 13:41:24