2017-08-08 144 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具有全局(##)範圍。

希望這會有所幫助。