2

该查询应该从 sql DB 中删除临时表/视图,但是当删除最后一个表/视图时,它会一直循环。任何人都有答案,为什么在删除最后一张表时会进入无限循环?

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 行受影响)删除了 VIEW:vue_SunsetCoveClientInventory

(1 行受影响)

(1 行受影响)删除 VIEW:vue_SunsetCoveClientCoOwners

(1 行受影响)

(受影响的 1 行)删除的表:BKDischarge

(1 行受影响)

(1 行受影响)删除 VIEW:vue_nocoop

(1 行受影响)

(1 行受影响)删除 VIEW:vue_nocoop

(0 行受影响)

(1 行受影响)删除 VIEW:vue_nocoop

(0 行受影响)

(1 行受影响)删除 VIEW:vue_nocoop

(0 行受影响)

(1 行受影响)删除 VIEW:vue_nocoop

(0 行受影响)

(1 行受影响)删除 VIEW:vue_nocoop

(0 行受影响)

4

1 回答 1

3

一旦您没有更多的行@tmp_table,您就不再更改 的值@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
于 2012-08-01T18:30:40.807 回答