【问题标题】:Issue with colunns in XML in SQL serverSQL Server 中 XML 列的问题
【发布时间】:2016-12-07 04:51:26
【问题描述】:

我有样本数据

DECLARE @Table1 TABLE (users int, ts int, name varchar(10), [1] int);

INSERT INTO @Table1 (users, ts, name, [1])
VALUES (1, 1, 'Raj', 0),
       (1, 3, 'maj', 2534),
       (1, 10, 'yes', 1458);

如果我尝试添加

select
    'test' as 'job/branch/FBEN/opcode',
    users AS 'job/branch/FBEN/opcode',
    name as 'job/branch/FBEN/opcode',
    [1] AS 'job/branch/FBEN/opcode/1'   
from 
    @Table1
where 
    ts = 3
for xml path('xmlexecute'), elements;

我收到一个错误:

消息 6850,第 16 级,状态 1,第 14 行
列名 'job/branch/FBEN/opcode/1' 包含 FOR XML 要求的无效 XML 标识符; '1'(0x0031) 是第一个错误字符。

我怎样才能得到这样的结果:

 <xmlexecute>
      <job>
        <branch>
          <FBEN>
            <opcode>1</opcode>
            <opcode>3</opcode>
            <opcode>maj</opcode>
             <1> 2534   </1>
          </FBEN>
        </branch>
      </job>
    </xmlexecute>

【问题讨论】:

  • XML 相当严格——你不能有一个以数字开头的元素名称。类似问题请见stackoverflow.com/questions/4756402/…
  • 那么我需要做的就是这个@JohnD
  • 老兄......还有什么可以回答的?使用任何其他不以数字字符开头的字符。不是火箭科学。
  • 例如,您可以使用job/branch/FBEN/opcode/column1 而不是job/branch/FBEN/opcode/1
  • 好的,那么我会向我的数据架构师@JohnD 提出相同的建议

标签: sql sql-server xml


【解决方案1】:

这与您的other question - with explanation 的答案相同:

不可能将元素命名为&lt;1&gt;! XML 不允许这样做! Look at "XML naming rules".

好吧,您可以创建一个看起来像 XML 的字符串,但这是一个字符串,而不是 XML。在大多数情况下,最好的选择是将此内容推送到属性的值中……这取决于您的需求。

顺便说一句:我真的会重新考虑将列命名为 [1]。这将是 - 肯定的! - 以后脖子疼……

DECLARE @Table1 TABLE (users int, ts int, name varchar(10), [1] int);

INSERT INTO @Table1 (users, ts, name, [1])
VALUES (1, 1, 'Raj', 0),
       (1, 3, 'maj', 2534),
       (1, 10, 'yes', 1458);
select
(
    select
        'test' as [opcode]
        ,''
        ,users AS [opcode]
        ,''
        ,name as [opcode] 
        ,''
        ,[1] AS [opcode] --or any other (valid) name, start with an "@" for an attribute
    from 
        @Table1
    where 
        ts = 1
    for xml path('FBEN'),ROOT('branch'),TYPE
) AS job
FOR XML PATH('xmlexecute')
;

结果

<xmlexecute>
  <job>
    <branch>
      <FBEN>
        <opcode>test</opcode>
        <opcode>1</opcode>
        <opcode>Raj</opcode>
        <opcode>0</opcode>
      </FBEN>
    </branch>
  </job>
</xmlexecute>

【讨论】:

    【解决方案2】:

    试试这个:(这正是你想要的结果):

    DECLARE @Table1 TABLE (users int, ts int, name varchar(10), [1] int);
    
    INSERT INTO @Table1 (users, ts, name, [1])
    VALUES 
    (1, 1, 'Raj', 0),       (1, 3, 'maj', 2534),       (1, 10, 'yes', 1458);
    
    select replace((replace((replace((
     select
        users AS 'job/branch/FBEN/opcode',
        ts as 'job/branch/FBEN/opcode1',
        name as 'job/branch/FBEN/opcode2',
        [1] AS 'job/branch/FBEN/zxdg1'   
    from 
        @Table1
    where 
        ts = 3
    for xml path('xmlexecute'), elements),'opcode1','opcode')),'opcode2','opcode')),'zxdg1','1')
    

    输出:

    <xmlexecute>
            <job>
               <branch>
                  <FBEN>
                   <opcode>1</opcode>
                   <opcode>3</opcode>
                   <opcode>maj</opcode>
                   <1>2534</1>
                </FBEN>
               </branch>
             </job>
     </xmlexecute>
    

    【讨论】:

    • 不!如果可能的话,不应在字符串级别处理 XML! 这会产生各种副作用,并可能导致绝对不可预测的错误。想象一下,“opcode1”这个词——为什么会——包含在其他地方……
    • 顺便说一句:你的输出是一个字符串。它看起来像 XML,但实际上不是。您将无法使用 XML 方法。试试CAST(YourResult AS XML)...你会得到和OP一样的错误...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多