在游标循环中执行插入

时间:2014-05-27 13:01:07

标签: sql ssms sql-insert database-cursor

我正在尝试从游标循环中将值插入临时表。这很难解释,所以我将展示到目前为止我所拥有的内容。

declare @sqlStatement varchar(max)
declare @tmpTable table (
    Table_Name varchar(max)
    ,Count int
)
declare cur CURSOR FAST_FORWARD FOR
    Select
        'Select ''' + TABLE_NAME + ''' [Table_Name],COUNT(*) [Count] From [' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'
    from information_schema.tables
    Where TABLE_TYPE = 'BASE TABLE'

OPEN cur
FETCH NEXT FROM cur
INTO @sqlStatement

WHILE @@FETCH_STATUS = 0
BEGIN
    declare @tmp varchar(max) = 'INSERT INTO @tmpTable ' + @sqlStatement 
    exec @tmp
    Select * From @tmpTable

    fetch next from cur
    into @sqlStatement
END

CLOSE cur
DEALLOCATE cur

我收到错误

The name 'INSERT INTO @tmpTable Select 'table' [Table_Name],COUNT(*) [Count] From [dbo].[table]' is not a valid identifier.

但我没有看到该陈述有任何错误。我认为它可能与字符串中的转义字符有关吗?

3 个答案:

答案 0 :(得分:2)

exec来电的格式必须包括括号:

exec(@tmp)

您还需要更改为#temp表,因为表变量不在exec批量范围内。

答案 1 :(得分:1)

尝试使用实际临时表而不是变量。动态SQL需要引用数据库对象。

create table #tmpTable (
    Table_Name varchar(max)
   ,Count int
)

答案 2 :(得分:1)

有几个问题,你的while循环缺失' FETCH NEXT FROM cur INTO @ sqlStatement'这将导致它无限循环。但这不是真正的问题。使用exec()括号,它应该解决问题。

或者如果我是你,我会尝试使用基于集合的语句来实现这一点,如下所示:

declare @tmpTable  table (
    Table_Name varchar(max),
    CountX int
)

insert into @tmpTable   
SELECT sc.name +'.'+ ta.name TableName
 ,SUM(pa.rows) CountX
 FROM sys.tables ta
 INNER JOIN sys.partitions pa
 ON pa.OBJECT_ID = ta.OBJECT_ID
 INNER JOIN sys.schemas sc
 ON ta.schema_id = sc.schema_id
 WHERE ta.is_ms_shipped = 0 AND pa.index_id IN (1,0)
 GROUP BY sc.name,ta.name
 ORDER BY SUM(pa.rows) DESC

 select * from @tmpTable