2017-08-08 61 views
0

我想使用动态查询来声明游标。基本上我有我将用作游标的表值函数的名称作为表的列,所以我必须使用SQL语句声明游标。如何在T-SQL中动态声明游标?

问题是T-SQL不能将myCursor识别为有效的游标。

DECLARE @ColumnA nvarchar(250) 
DECLARE @ColumnB nvarchar(250) 
DECLARE @FunctionName nvarchar(250) 
DECLARE @RecordId nvarchar(250) 
DECLARE @sqlStatement nvarchar(MAX) 

SET @sqlStatement = 'DECLARE myCursor CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR SELECT * FROM ' + @FunctionName + '(''' + @RecordId + ''')' 

EXEC sp_executesql @sqlStatement 

OPEN myCursor 

FETCH NEXT FROM myCursor INTO @ColumnA, @ColumnB 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SELECT @ColumnA, @ColumnB 

    FETCH NEXT FROM myCursor INTO @ColumnA, @ColumnB 
END 

CLOSE myCursor 
DEALLOCATE myCursor 

欢迎任何帮助或解决方法。

编辑:我解决了这个问题,通过声明游标之前和使用sqlstatement的输出传递值。

DECLARE @myCursor CURSOR

SET @sqlStatement = 'SET @myCursor = CURSOR局部静态READ_ONLY FORWARD_ONLY FOR SELECT * FROM' + @FunctionName + '(' '' + @RecordId + '''); OPEN @myCursor;”

EXEC sp_executesql的@sqlStatement,N '@占位符为nvarchar(250),@Placeholdervalue为nvarchar(250),@myCursor CURSOR OUTPUT',@Placeholder = @Placeholder,@Placeholdervalue = @Placeholdervalue,@myCursor = @myCursor OUTPUT

+1

这听起来像一个[xy问题](https://meta.stackexchange.com/q/66377/179361)。你究竟在努力实现什么?我无法想象这是最好的解决方案。在使用SQL Server的10年中,我可以诚实地说我从未遇到过需要动态声明的游标的场景。你怎么知道你的函数会返回至少两列?你怎么知道这些列将是'nvarchar(250)'?你怎么知道一个有效的函数名已经发布?你怎么知道你的函数接受一个nvarchar(250)参数? – GarethD

回答

0

这不是最好的解决方案,但是如果你真的需要这样做 - 更简单的方法是使用动态SQL将所需数据首先加载到全局临时表中。动态SQL语句要简单得多,即:

SET @sqlStatement = 'SELECT * INTO ##MyGlobalTemp FROM ' + @FunctionName + '(''' + @RecordId + ''')' 
EXEC sp_executesql @sqlStatement 

然后通过## MyGlobalTemp表使用常规(非动态)游标循环(不要忘记您完成后删除临时)。

即:

DECLARE myCursor CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR SELECT column1, column2, etc.. FROM ##MyGlobalTemp...... etc.. 

动态游标可能会很麻烦。只要确保temp具有全局(##)范围。

希望这会有所帮助。