在SQL select请求期间从XML字符串中检索元素值

时间:2018-06-11 16:41:16

标签: sql-server xml tsql xquery

我正在查询一个表T,它有一个字符串列StrXML,其中包含XML文本。以下是存储的XML示例:

<Sequence mc:Ignorable="sap sads" DisplayName="Post Processing" 
          sap:VirtualizedContainerService.HintSize="424,318" 
          mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces"
          xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006
          xmlns:mee="clr-namespace:MatX.eRP.Entities;assembly=eRP.Entities"
          xmlns:mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities"
          xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities"
          xmlns:sads="http://schemas.microsoft.com/netfx/2010/xaml/activities/debugger"
          xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
          xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <sap:WorkflowViewStateService.ViewState>
        <scg:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
        </scg:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <mepa:BasicOperation Description="Traitement Thermique" DisplayName="HeatTreatment" Guid="82800b59-e181-4a93-b483-7e2cd9b14827"     sap:VirtualizedContainerService.HintSize="402,154" Scope="Build">
        <mepa:BasicOperation.MeasurementDescriptions>
            <scg:List x:TypeArguments="mee:MeasurementDescription" Capacity="0" />
        </mepa:BasicOperation.MeasurementDescriptions>
    </mepa:BasicOperation>
    <mepa:BasicOperation Description="Finition manuelle" DisplayName="Manual Finishing" Guid="cd64be75-6968-47fe-8aac-93a4fdf37892">
        <mepa:BasicOperation.MeasurementDescriptions>
            <scg:List x:TypeArguments="mee:MeasurementDescription" Capacity="4">
                <mee:MeasurementDescription Max="{x:Null}" Min="{x:Null}" Guid="7c1a37f1-f39d-4ed3-8048-6b0a266c70b9" IsRequired="False" Name="MesureMF1" Type="Double" />
                <mee:MeasurementDescription Max="{x:Null}" Min="{x:Null}" Guid="a21b0c0d-dfff-4237-9975-4179bcefe7c2" IsRequired="False" Name="MesureMF2" Type="Double" />
            </scg:List>
        </mepa:BasicOperation.MeasurementDescriptions>
    </mepa:BasicOperation>
</Sequence>

在表T上的选择请求中,我只想显示Description的{​​{1}}值。

我该怎么做?

2 个答案:

答案 0 :(得分:0)

尝试类似这样的事情,假设这是针对 SQL Server

;WITH  XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/netfx/2009/xaml/activities', 
                     'clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities' AS mepa)
SELECT 
    T.X.value('@Description', 'varchar(100)') AS JobTitle
FROM 
    @XTable
CROSS APPLY
    XmlData.nodes('/Sequence/mepa:BasicOperation') AS T(X)
WHERE
    T.X.value('@Guid','varchar(50)') = '82800b59-e181-4a93-b483-7e2cd9b14827'

答案 1 :(得分:0)

在我之前提到的评论中,您的一个命名空间缺少最终的"。这是一个很大的问题,如果它不只是一个复制粘贴问题......(不是格式良好

XML不应存储在字符串列中(缓慢且危险!)。如果您的数据库本身不支持XML,则至少应该检查XML。

你没有提到实际的RDBMS,但是XQuery原则应该是相同的(但是你的RDBMS实际上是在处理XQuery)。

简单的方法就是XQuery(获取任何 <BasicOperation>,无论放置在哪里,并过滤给定的GUID)

//*:BasicOperation[@Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/@Description

使用SQL-Server,您可以尝试这个

SELECT CAST(T.StrXML AS XML).value(N'(//*:BasicOperation[@Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/@Description)[1]',N'nvarchar(max)')

更具体(和推荐)的方法是:

declare namespace dflt="http://schemas.microsoft.com/netfx/2009/xaml/activities";
declare namespace mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities";
dflt:Sequence/mepa:BasicOperation[@Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/@Description

再次 - 使用SQL-Server - 你可以试试这个:

SELECT CAST(T.StrXML AS XML).value(N'declare namespace dflt="http://schemas.microsoft.com/netfx/2009/xaml/activities";
                                     declare namespace mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities";
                                     (dflt:Sequence/mepa:BasicOperation[@Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/@Description)[1]',N'nvarchar(max)')

如果GUID值是可变的,SQL-Server将允许您从外部声明的变量中传入值。阅读sql:variable()sql:column()

更新

您可以使用lower-case()进行安全比较:

 DECLARE @xml XML=
'<root>
   <a guid="82800b59-e181-4a93-b483-7e2cd9b14827" /> 
   <a guid="82800B59-E181-4A93-B483-7E2CD9B14827" /> 
 </root>';

 DECLARE @guid UNIQUEIDENTIFIER='82800B59-E181-4A93-B483-7E2CD9B14827';

 SELECT @xml.query(N'/root/a[lower-case(@guid)=lower-case(sql:variable("@guid"))]')