使用FOR XML PATH在XML中插入SQL查询的内容

时间:2013-09-15 21:17:33

标签: sql-server xml for-xml-path

我编写了一个存储过程,它返回包含一些生成的SQL查询的nvarchar变量,以及第二个过程,它使用FOR XML PATH生成XML。 我想修改生成XML的过程,并将生成的查询的内容从第一个过程添加到生成的XML中。

生成XML的程序的一部分:

SELECT @SQLStr = 'SELECT';

    DECLARE @tmp varchar(100), @tmpkod varchar(max);
    DECLARE c CURSOR LOCAL READ_ONLY FOR
    SELECT tableName, tableCode FROM @TableNames 
    OPEN c
    FETCH NEXT FROM c INTO @tmp, @tmpkod;
    WHILE @@FETCH_STATUS = 0 
    BEGIN

    SELECT @i = @i - 1;
    SELECT @SQLStr = @SQLStr + '(SELECT TOP 10 * FROM ' + @tmp + ' FOR XML PATH(''row''), TYPE) AS ' + @tmp + ',
    '
    EXEC GenerujSelectazXML @tmp, @tmpcode output;

    SELECT @SQLStr = @SQLStr + '(SELECT ' + @tmpCode + ' FOR XML PATH (''row''), TYPE) AS ' + @tmp + '_TEST'
    SELECT @tmpcode

    IF (@i <> 0) SELECT @SQLStr = @SQLStr + ',
    '
    ELSE SELECT  @SQLStr = @SQLStr + '
    '
    FETCH NEXT FROM c INTO @tmp, @tmpkod;
    END
    CLOSE c; DEALLOCATE c;

    SELECT @SQLStr = @SQLStr + 'FOR XML PATH(''''), ROOT(''root'')';

    EXEC (@SQLStr) 

我不能简单地将查询内容放入XML中,因为它包含一些特殊字符,如“&lt;”,“&gt;”,它们正在引入/结束xml标记。 所以我认为将查询命令放入XML注释将解决我的问题。

我试过了:

    SELECT @SQLStr = '<!--' + @tmpCode + '-->';

并没有帮助,我收到了错误:

  

Msg 102,Level 15,State 1,Line 3
  '&lt;'附近的语法不正确   Msg 137,Level 15,State 1,Line 4
  必须声明标量变量“@xml”   消息137,级别15,状态2,行216   必须声明标量变量“@xml”   消息156,15级,状态1,行217   关键字“FOR”附近的语法不正确。
  消息137,级别15,状态1,行219   必须声明标量变量“@xml”   Msg 137,Level 15,State 2,Line 416
  必须声明标量变量“@xml”   信息156,第15级,状态1,第417行
  关键字“FOR”附近的语法不正确。
  Msg 137,Level 15,State 1,Line 419
  必须声明标量变量“@xml”   Msg 137,Level 15,State 2,Line 540
  必须声明标量变量“@xml”。

我也试过这个:

SELECT @SQLStr = '<![CDATA[' + @tmpCode + N']]>';

也没有帮助。

我收到错误消息:

  

Msg 102,Level 15,State 1,Line 3
  '&lt;'附近的语法不正确   Msg 103,Level 15,State 4,Line 3
  与CDATA开始标识符[DECLARE @xml XML SELECT TOP 1 @xml = X FROM iksemel ORDER BY ID INSERT INTO ARTYKUL_TEST(ID_ARTYKULU,ID_MAGAZYNU”被太长。最大长度是128。
  Msg 105,Level 15,State 1,Line 541
  字符串')'后面的未闭合引号。

请帮忙

1 个答案:

答案 0 :(得分:1)

您能提供一个您尝试生成的xml示例吗?根据您发布的代码,我假设它看起来像这样。

<root>
  <Instructors>
    <row>
      <InstructorName>Graff</InstructorName>
    </row>
  </Instructors>
 <Instructors_TEST>
   <row>0</row>
 </Instructors_TEST>
</root>

您需要将生成的SQL修改为更像这样:

SELECT (
  SELECT * FROM Instructors FOR XML PATH('row'), TYPE
) AS Instructors,
(
  SELECT 0 FROM Instructors FOR XML PATH('row'), TYPE
) AS Instructors_TEST
FOR XML PATH(''), ROOT('root')

问题不在于您尝试存储在xml中的值(查询)。在@tmpCode上执行SELECT,将其粘贴到编辑器中,并检查它是否是有效的字符串。不是。

在你的代码中,你得到了这个:

SELECT @tmpCode = '''SELECT value(''ID_ARTYKULU[1]'')'''
--'SELECT value('ID_ARTYKULU[1]')'

但你想用这个:

SELECT @tmpCode = '''SELECT value(''''ID_ARTYKULU[1]'''')'''
--'SELECT value(''ID_ARTYKULU[1]'')'

一个贫民窟修复方法是用这个替换你的@tmpCode部分:

SELECT @tmpCode = N'''' + REPLACE('SELECT value(''ID_ARTYKULU[1]'')', N'''', N'''''') + N''''

由于您正在使用动态SQL,因此在转义引号时需要非常小心。