在SQL Server中,有没有办法避免使用Cursor?

时间:2010-07-05 09:41:45

标签: sql-server cursor dynamic-sql

我有一个表,其中每个记录都有一个Table_Name(表的名称)。然后,我使用Cursor选择与Cursor中的某些记录相关的所有表名。然后我为Cursor中的每个表名做一个WHILE来做一些工作。

我想知道是否可以在不使用光标的情况下解决此问题。

DECLARE tables_cursor CURSOR FAST_FORWARD FOR SELECT Table_Name FROM Some_Table WHERE ...

FETCH NEXT FROM tables_cursor INTO @Dynamic_Table_Name
WHILE @@FETCH_STATUS = 0
BEGIN
...
END

游标中的Foreach表名我执行动态SQL查询,如下所示:

SELECT @sql = '
    UPDATE dbo.' + @Dynamic_Table_Name + '
    SET ...'
EXEC sp_executesql @sql, @params, ...

我的问题是:是否可以避免使用Cursor来解决这个问题?

不幸的是,无法更改具有引用表的表名的设计,如果可以的话,我会立即做的。

3 个答案:

答案 0 :(得分:1)

是的,您可以避开光标,但无法避免动态查询。

您可以创建一个查询,将所有连接在一起的动态查询作为单个字符串返回。这样你就可以在不使用循环的情况下执行它们,但这并不是更好......

如果无法更改数据库设计,则会遇到动态查询。

答案 1 :(得分:1)

嗯,您可以隐藏使用游标(使用未记录但广泛使用的)MS存储过程sp_MSforeachdb(Google有很多示例);但是它在内部使用了一个光标,所以如果这是一个哲学上的反对意见,那么这并没有真正的帮助。

我不认为可以是一种基于集合的方式来做这种事情,因为每个表可能都有不同的关系结构。

答案 2 :(得分:1)

,您可以在不使用游标的情况下解决此问题。相反,您需要引入新表,该表存储来自实际表的表名以及自动生成的id列。

查看以下示例查询

declare @test table (id  int identity,tableName varchar(20))

insert into @test 
            select 'abc' union all
            select '123' union all
            select '345' union all
            select 'sdf' union all
            select 'uhyi' 

而不是查询,您可以使用您的查询来填充表变量

insert into @test 
  SELECT Table_Name FROM Some_Table WHERE ...   

--select * from @test

declare @cnt int
declare @incr int
select @cnt = count(id) from @test
set @incr = 1
while (@incr <= @cnt)
begin
    select tableName from @test where id = @incr
    set @incr =@incr + 1
end