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 行) TABLE:BKDischarge を削除

(1 行が影響を受けます)

(影響を受ける 1 行) 削除された VIEW:vue_nocoop

(1 行が影響を受けます)

(影響を受ける 1 行) 削除された VIEW:vue_nocoop

(影響を受ける行はありません)

(影響を受ける 1 行) 削除された VIEW:vue_nocoop

(影響を受ける行はありません)

(影響を受ける 1 行) 削除された VIEW:vue_nocoop

(影響を受ける行はありません)

(影響を受ける 1 行) 削除された VIEW:vue_nocoop

(影響を受ける行はありません)

(影響を受ける 1 行) 削除された VIEW:vue_nocoop

(影響を受ける行はありません)

4

1 に答える 1

3

に行@tmp_tableがなくなると、 の値は変更されなくなります@name。私はあなたがむしろ使用したいと思います:

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

このスタイルのチェックに変更すると、次の利点もあります。

  • 開始する行が少なくとも 1 つあるとは想定していません。
  • SELECT TOP 1...2 つの場所で同じものを維持する必要はありません。

このデモ コードを実行すると、問題を簡略化された形式で確認できます。

-- 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 に答える