2012-08-01 118 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