有没有更好的方法来执行不使用游标的动态SQL?

时间:2012-08-06 18:06:53

标签: sql sql-server-2005 cursor execute dynamic-sql

我有一个存储在SQL表中的动态SQL,我必须在某些条件下执行它。目前,我们使用游标来处理这个问题,但我总是被告知尽可能避免使用游标,因为它们不是最有效的方法。所以,我的问题是:如何在没有它们的情况下执行动态SQL(如果有办法)?整个系统是围绕这个动态SQL混乱构建的,所以没有改变它。

为此,假设该表具有Id AS IDENTITYSQL AS VARCHAR字段,其中SQL字段包含要执行的SQL(显然)。

修改 基本上,我想循环遍历表并在SQL列中执行SQL。

因此,表格中的一行基本上如下所示:

ID   SQL
--   ----------------------
1    SELECT * FROM RECORD
2    SELECT * FROM PERSON
3    SELECT * FROM LOCATION

我没有编写任何代码,因为我写的是一个遍历表并执行它的游标。我只是不知道有什么其他循环表并将该字符串作为SQL查询执行的方法,而不是像以下那样:

DECLARE @sql VARCHAR(MAX)

DECLARE _cursor CURSOR
FOR
    SELECT  [SQL]
    FROM    #tmp2

OPEN _cursor

FETCH NEXT FROM _cursor INTO @sql

WHILE @@FETCH_STATUS = 0 
    BEGIN
        PRINT ( @sql )
    END
CLOSE _cursor   
DEALLOCATE _cursor

2 个答案:

答案 0 :(得分:3)

你可以使用任意数量的串联技巧来制作一个大批量而不使用游标,我个人经常使用FOR XML技巧。

以下是概述:

http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/

然而,光标(虽然通常是代码气味)不会对此不表现造成可怕的影响。而且,与单批次相比,您将有机会更轻松地处理错误等。

此外,如果某些语句中的DDL必须是批处理中的第一个语句,那么您需要在不同的批处理中提交它们。 EXEC或sp_executesql没有实现任何批处理拆分,如SSMS具有GO批处理分隔符。

答案 1 :(得分:2)

忽略整个架构中的根本缺陷......

declare @sql nvarchar(max) 
   select @sql = '' 
   select @sql = @sql + SQL + ';' from #tmp2  

   exec sp_executesql @sql

至少我们现在已经摆脱了光标:)

编辑:代码对我有用......

create table #tmp2 (sql nvarchar(100))
insert #tmp2 values ('select * from sysobjects')
insert #tmp2 values  ('Select * from sysColumns')    
declare @sql nvarchar(max) 
   select @sql = '' 
   select @sql = @sql + SQL + ';' from #tmp2       
   exec sp_executesql @sql        
drop table #tmp2