2016-04-29 36 views
4
DECLARE @TablesList TABLE 
(
    TableName VARCHAR(500), 
    RefTable VARCHAR(500), 
    RefTableIDColumn VARCHAR(500) 
) 
DECLARE @Query AS VARCHAR(MAX) 


SET @Query = 'DECLARE @badIds AS VARCHAR(500) DECLARE @TableXML AS XML' 
SET @Query = @Query + ' SELECT @TableXML = xCol FROM (SELECT * FROM OPENROWSET (BULK ''\\10.0.0.60\Temp\path\DataItemTables.xml'', SINGLE_CLOB)AS xCol) AS R(xCol)' 
SET @Query = @Query + ' INSERT INTO @TablesList SELECT ref.value(''tablename[1]'',''nvarchar(500)'') AS tablename,' 
SET @Query = @Query + ' ref.value(''refTable[1]'',''nvarchar(500)'') AS refTable, ref.value(''refTableIDColumn[1]'',''nvarchar(500)'') AS refTableIDColumn FROM' 
SET @Query = @Query + ' @TableXML.nodes(''//Table[@name="Description"]'') AS R(ref)' 
SET @Query = @Query +'select * from @TablesList' 

EXEC(@Query) 

我正在执行上述脚本。但我得到如下错误从sql服务器中的XML文件中提取XML数据时出错

Msg 1087, Level 15, State 2, Line 1 
Must declare the table variable "@TablesList". 
Msg 1087, Level 15, State 2, Line 1 
Must declare the table variable "@TablesList". 

我做错了什么。但是当我用下面的动态形式编写查询时,它可以正常工作。问题是我想删除SP的所有动态部分。

DECLARE @Query AS VARCHAR(MAX) 

SET @Query ='DECLARE @TablesList TABLE (TableName VARCHAR(500),RefTable VARCHAR(500),RefTableIDColumn VARCHAR(500))' 
SET @Query = @Query + ' DECLARE @badIds AS VARCHAR(500) DECLARE @TableXML AS XML' 
SET @Query = @Query + ' SELECT @TableXML = xCol FROM (SELECT * FROM OPENROWSET (BULK ''\\10.0.0.60\Temp\Path\DataItemTables.xml'', SINGLE_CLOB)AS xCol) AS R(xCol)' 
SET @Query = @Query + ' INSERT INTO @TablesList SELECT ref.value(''tablename[1]'',''nvarchar(500)'') AS tablename,' 
SET @Query = @Query + ' ref.value(''refTable[1]'',''nvarchar(500)'') AS refTable, ref.value(''refTableIDColumn[1]'',''nvarchar(500)'') AS refTableIDColumn FROM' 
SET @Query = @Query + ' @TableXML.nodes(''//Table[@name="Description"]'') AS R(ref)' 
SET @Query = @Query +'select * from @TablesList' 

EXEC(@Query) 

回答

4

您只能在声明它的同一范围内访问表变量。由于您的EXEC位于不同的作用域中,因此无法识别表变量。解决此问题的一种方法是使用临时表代替:

CREATE TABLE #TablesList 
(
    TableName VARCHAR(500), 
    RefTable VARCHAR(500), 
    RefTableIDColumn VARCHAR(500) 
) 
DECLARE @Query AS VARCHAR(MAX) 

SET @Query = 'DECLARE @badIds AS VARCHAR(500) DECLARE @TableXML AS XML' 
SET @Query = @Query + ' SELECT @TableXML = xCol FROM (SELECT * FROM OPENROWSET (BULK ''\\10.0.0.60\Temp\path\DataItemTables.xml'', SINGLE_CLOB)AS xCol) AS R(xCol)' 
SET @Query = @Query + ' INSERT INTO #TablesList SELECT ref.value(''tablename[1]'',''nvarchar(500)'') AS tablename,' 
SET @Query = @Query + ' ref.value(''refTable[1]'',''nvarchar(500)'') AS refTable, ref.value(''refTableIDColumn[1]'',''nvarchar(500)'') AS refTableIDColumn FROM' 
SET @Query = @Query + ' @TableXML.nodes(''//Table[@name="Description"]'') AS R(ref)' 
SET @Query = @Query +'select * from #TablesList' 

EXEC(@Query) 
+0

它的工作,谢谢。我可以使上述查询更静态而不是动态。 – user2998990

+1

当然,我会把它留给你作为练习。 –

+0

@ user2998990你有任何理由使用动态SQL吗?如果您将'EXEC(@Query)'更改为''SELECT @ Query',那么您将得到查询的文本而不需要很多工作,只需要一些格式化。不要忘记将输出的文本长度设置为8192(最大值),否则SSMS将不会显示整个区域... – Shnugo

相关问题