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