【问题标题】:Inserting content of SQL query in XML using FOR XML PATH使用 FOR XML PATH 在 XML 中插入 SQL 查询的内容
【发布时间】:2013-09-15 21:17:33
【问题描述】:

我编写了一个存储过程,它返回包含一些生成的 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,因为它包含一些特殊字符,如“”,它们正在引入/结束 xml 标记。 所以我认为将查询命令放入 XML 注释将解决我的问题。

我试过了:

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

它没有帮助,我得到了错误:

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

我也试过这个:

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

也没有用。

我收到的错误消息:

消息 102,第 15 级,状态 1,第 3 行
' 消息 103,第 15 级,状态 4,第 3 行
以 CDATA[DECLARE @xml xml SELECT TOP 1 @xml = x FROM iksemel ORDER BY id INSERT INTO ARTYKUL_TEST(ID_ARTYKULU,ID_MAGAZYNU' 开头的标识符太长。最大长度为 128。
消息 105,15 级,状态 1,541 行
字符串')'后面的非闭合引号。

请帮忙

【问题讨论】:

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


【解决方案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,因此在转义引号时需要非常小心。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 2021-11-15
    相关资源
    最近更新 更多