情況1:資料存到外部變數
ALTER PROCEDURE [dbo].[Test]
@QueryXML nvarchar(max),
@Result xml out
AS
BEGIN
declare @tmpCmd nvarchar(max);
set @tmpCmd = '@Result = (select ' + @QueryXML + '
from [GA_Survey_ForXML]
for xml auto);';
EXEC sp_executesql @tmpCmd;
END
上面會出錯... Must declare the scalar variable "@Result".
需要用別種方式
ALTER PROCEDURE [dbo].[Test]
@QueryXML nvarchar(max),
@Result xml out
AS
BEGIN
declare @tmpCmd nvarchar(max);
-- 所要執行的SQL
set @tmpCmd = '(select ' + @QueryXML + '
from [GA_Survey_ForXML]
for xml auto);';
-- 執行結果丟到暫存變數
set @tmpCmd = N'set @x = ' + @tmpCmd;
-- 執行exec executesql的時候
-- 定義變數@x的型別及可輸出資料至外部行程使用
-- 再來使用原行程的變數@Result來接手@x的資料
EXEC sp_executesql @tmpCmd, N'@x xml output',@x = @Result out;
END
若用debug模式來看程式碼的運作程序
當在執行EXEC sp_executesql時會另起程序 (inner)
所以SQL字串內部的變數與原先執行SQL程序(outer)的變數…毫無相干
也就是不行調用其他程序的變數 (我目前的知識跟我說的...可能2008改的有辦法也不一定XD)
--
情況2:操作外部變數的資料
ALTER PROCEDURE [dbo].[Test]
@QueryXML nvarchar(max),
@QueryXML2 nvarchar(max),
@Result xml out
AS
BEGIN
declare @tmpCmd nvarchar(max);
set @Result = '(select ' + @QueryXML + '
from [GA_Survey_ForXML]
for xml auto);';
SET @tmpCmd = N'set @x = ' + @tmpCmd;
EXEC sp_executesql @tmpCmd, N'@x xml output',@x = @Result out;
-- 暫存的Table
IF OBJECT_ID('tempdb..#t') IS NOT NULL
BEGIN
DROP TABLE #t;
END
CREATE TABLE #t(
ResultXML xml
);
-- 將變數資料存到暫存Table
INSERT INTO #t VALUES (@Result);
-- 內部程序藉由暫存Table取得外部程序變數資料
set @tmpCmd = '(select ResultXML.query(''' + @QueryXML2 + ''') from #t);'
set @tmpCmd = N'set @x = ' + @tmpCmd;
EXEC sp_executesql @sql, N'@x xml output',@x = @Result out
END
--
此預儲程序的@QueryXML和@QueryXML2
因專案所需,是server傳入動態生成的XML query的指令…
不然也用不到sp_executesql
按...雖然XML對我這次的專案擴充性很佳
但拎北對XML的操作真的還不是很熟且杜蘭...