在Sql Server中查询包含序列化对象的Xml数据

时间:2014-11-10 11:52:07

标签: tsql xpath xquery-sql

我们将一些序列化对象存储在Sql Server的Xml列中。

我想创建一个查询,它给出了特定字段具有特定值的序列化对象(行)列表。

我的Xml看起来像这样:

<MessageContainer xmlns="http://schemas.datacontract.org/2004/07/D3A.Messages" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="1" z:Type="D3A.Messages.MessageContainer" z:Assembly="D3A.Messages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
  <Messages xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" z:Id="2" z:Type="System.Collections.Generic.List`1[[D3A.Messages.IMessage, D3A.Messages, Version=1.0.0.0, Culture=neutral,   PublicKeyToken=null]]" z:Assembly="0">
    <a:_items z:Id="3" z:Size="512">
      <a:anyType z:Id="4" z:Type="D3A.Messages.MessageAlarmLog" z:Assembly="D3A.Messages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <_x003C_Id_x003E_k__BackingField>00000000-0000-0000-0000-000000000000</_x003C_Id_x003E_k__BackingField>
        <_x003C_StorageOperation_x003E_k__BackingField>Create</_x003C_StorageOperation_x003E_k__BackingField>
        <_x003C_Comment_x003E_k__BackingField z:Id="5" />
        <_x003C_ErrorCodeTranslation_x003E_k__BackingField>Ok</_x003C_ErrorCodeTranslation_x003E_k__BackingField>
        <_x003C_ErrorCode_x003E_k__BackingField>0</_x003C_ErrorCode_x003E_k__BackingField>
        <_x003C_GroupType_x003E_k__BackingField>System</_x003C_GroupType_x003E_k__BackingField>
        <_x003C_LogType_x003E_k__BackingField z:Id="6">1</_x003C_LogType_x003E_k__BackingField>
        <_x003C_Parameter_x003E_k__BackingField z:Id="7">Timed out.</_x003C_Parameter_x003E_k__BackingField>
        <_x003C_TimeStampOff_x003E_k__BackingField i:nil="true" />
        <_x003C_TimeStamp_x003E_k__BackingField>2014-05-10T03:10:04Z</_x003C_TimeStamp_x003E_k__BackingField>
        <_x003C_Unit_x003E_k__BackingField z:Id="8">100001</_x003C_Unit_x003E_k__BackingField>
        <_x003C_UserName_x003E_k__BackingField z:Id="9">e2_fælles</_x003C_UserName_x003E_k__BackingField>
        <_x003C_Value_x003E_k__BackingField z:Id="10">50101</_x003C_Value_x003E_k__BackingField>
        <_x003C_WindFarm_x003E_k__BackingField z:Id="11">HR2</_x003C_WindFarm_x003E_k__BackingField>
      </a:anyType>
      <a:anyType z:Id="12" z:Type="D3A.Messages.MessageAlarmLog" z:Assembly="D3A.Messages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <_x003C_Id_x003E_k__BackingField>00000000-0000-0000-0000-000000000000</_x003C_Id_x003E_k__BackingField>
        <_x003C_StorageOperation_x003E_k__BackingField>Create</_x003C_StorageOperation_x003E_k__BackingField>
        <_x003C_Comment_x003E_k__BackingField z:Ref="5" i:nil="true" />
        <_x003C_ErrorCodeTranslation_x003E_k__BackingField>Ok</_x003C_ErrorCodeTranslation_x003E_k__BackingField>
        <_x003C_ErrorCode_x003E_k__BackingField>0</_x003C_ErrorCode_x003E_k__BackingField>
        <_x003C_GroupType_x003E_k__BackingField>System</_x003C_GroupType_x003E_k__BackingField>
        <_x003C_LogType_x003E_k__BackingField z:Id="13">1</_x003C_LogType_x003E_k__BackingField>
        <_x003C_Parameter_x003E_k__BackingField z:Ref="5" i:nil="true" />
        <_x003C_TimeStampOff_x003E_k__BackingField i:nil="true" />
        <_x003C_TimeStamp_x003E_k__BackingField>2014-05-10T03:10:09Z</_x003C_TimeStamp_x003E_k__BackingField>
        <_x003C_Unit_x003E_k__BackingField z:Id="14">100001</_x003C_Unit_x003E_k__BackingField>
        <_x003C_UserName_x003E_k__BackingField z:Id="15">e2_fælles</_x003C_UserName_x003E_k__BackingField>
        <_x003C_Value_x003E_k__BackingField z:Id="16">50100</_x003C_Value_x003E_k__BackingField>
        <_x003C_WindFarm_x003E_k__BackingField z:Ref="11" i:nil="true" />
      </a:anyType>
    </a:_items> 
  </Messages>
</MessageContainer>

我对那些名为_x003C_Unit_x003E_k__BackingField的Xml字段中具有特定值的Xml块特别感兴趣。可能有许多<a:anytype> - 片段,我对完整<MessagesContainer> - 至少有一个<a:anyType>符合我标准的片段感兴趣。

你能在这帮吗?我似乎无法在查询中获得名称空间声明。

谢谢: - )

1 个答案:

答案 0 :(得分:1)

在下面的查询中,将“100001”替换为所需的值。如果需要,您可以使用sql:variable()使此值动态化。

select @x.query('
    declare namespace d3a="http://schemas.datacontract.org/2004/07/D3A.Messages";
    declare namespace a="http://schemas.microsoft.com/2003/10/Serialization/Arrays";
    /d3a:MessageContainer[
        d3a:Messages[
            a:_items[
                a:anyType[d3a:_x003C_Unit_x003E_k__BackingField/text() = "100001"]
            ]
        ]
    ]'
);

有关如何在XQuery中处理命名空间的更多详细信息,请参阅this article