1

我将动态 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
4

2 回答 2

3

您可以使用任意数量的连接技巧来制作一个大批量,而无需使用游标,我个人经常使用该FOR XML技巧。

这是一个概述:

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

但是,游标(虽然通常是代码味道)不会对它的非性能造成可怕的影响。并且您将有机会比单个批次更容易处理错误等。

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

于 2012-08-06T19:03:14.100 回答
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
于 2012-08-06T18:54:58.107 回答