这个查询应该是从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行) 丢弃的视图:vue_SunsetCoveClientInventory
(1行受影响)
(1行(s)受影响) 丢弃的视图:vue_SunsetCoveClientCoOwners
(1行受影响)
(1行(s)受影响) 丢弃的表:BKDischarge
(1行受影响)
(1行(s)受影响) 丢弃的视图:vue_nocoop
(1行受影响)
(1行(s)受影响) 丢弃的视图:vue_nocoop
(0行(s)受影响)
(1行(s)受影响) 丢弃的视图:vue_nocoop
(0行(s)受影响)
(1行(s)受影响) 丢弃的视图:vue_nocoop
(0行(s)受影响)
(1行(s)受影响) 丢弃的视图:vue_nocoop
(0行(s)受影响)
(1行(s)受影响) 丢弃的视图:vue_nocoop
(0行(s)受影响)
答案 0 :(得分: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