如何从SQL Server 2012中的下一级XML层次结构中查询另一个属性?

2022-04-02 00:00:00 xml xpath xquery sql-server

我对XML非常陌生,需要一些帮助来查询SQL Server 2012中的XML列。

到目前为止,我有以下声明:

SELECT sel.value('@name', 'varchar(max)')  AS SelectionParamterNames
FROM [schm].[sometable] T1
CROSS APPLY Selection.nodes('//syntax/selections/selection') R(sel)

到目前为止还不错,因为我从第三个层次结构中拿回了期望值:

选择参数名称

  1. SomeSelName_A
  2. SomeSelName_B

但我还需要的是<actionobject>中的name属性(如果存在,SomeSelName_B没有)

我以为这样就行了:

    SELECT   sel.value('@name', 'varchar(max)')  AS SelectionParamterNames
           , sel.value('.//@name', 'varchar(max)')  AS SelectionProcedureNames
    FROM [schm].[sometable] T1
    CROSS APPLY Selection.nodes('//syntax/selections/selection') R(sel)

我期望的是:

SelectionParameterNames | SelectionProcedureNames
--------------------------------------------------     
 1. SomeSelName_A       | sp_someprocedure_a 
 2. SomeSelName_B       | NULL

但我得到的是:

XQuery值‘[Structure.TM_TemplateVersion.Selection.value()]:()’ 需要单例(或空序列),找到的操作数类型 ‘xdt:untypeATIONAL*’

我花了相当长的时间来了解语法,但时间不多了,我需要一些帮助。

非常感谢,皮特

XML内容:

<syntax type="Selection">
  <selections>
    <selection type="Selection" name="SomeSelName_A" caption="SomeSelCaption_A" control="List" multivalue="True" clonetemplate="False" description="">
      <actionobject type="DbObject" datasourcename="SomeSource" objecttype="StoredProcedure" schema="schm" initialsql="schm.sp_someprocedure_a 1" name="sp_someprocedure_a">
        <parameters>
          <parameter name="@p_parameter_a" type="Parameter" datatype="Int" inputtype="Constant" inputvalue="1" required="False" iskey="False" />
          <parameter name="@p_parameter_b" type="Parameter" datatype="Int" inputtype="Constant" inputvalue="1" required="False" iskey="False" />
        </parameters>
        <columns>
          <column name="SomeColID_A" type="Column" datatype="Int" iskey="False" useas="Value" />
          <column name="SomeColName_A" type="Column" datatype="VarChar" iskey="False" useas="Text" />
        </columns>
      </actionobject>
    </selection>
    <selection type="Selection" name="SomeSelName_B" caption="SomeSelCaption_B" control="Calender" multivalue="false" clonetemplate="False" description="" />
  </selections>
</syntax>

解决方案

您需要告诉您要访问<actionobject>子节点!

使用以下语句:

SELECT   
    SelectionParamterNames = sel.value('@name', 'varchar(max)'),
    SelectionProcedureNames = sel.value('(actionobject/@name)[1]', 'varchar(50)')
FROM 
    [schm].[sometable] T1
CROSS APPLY 
    Selection.nodes('/syntax/selections/selection') R(sel)

您应该会得到所需的输出。

如果您的<selection>节点始终最多包含一个<actionobject>类型的元素,并且它将读取该元素的name属性-如果存在(否则您将返回NULL)

,则这将起作用

更新:如果<selection>下可以有多个<actionobject>节点,则需要执行"嵌套"CROSS APPLY

SELECT   
    SelectionParamterNames = sel.value('@name', 'varchar(max)'),
    SelectionProcedureNames = ActObj.value('@name', 'varchar(50)')
FROM 
    [schm].[sometable] T1
CROSS APPLY 
    Selection.nodes('/syntax/selections/selection') R(sel)
CROSS APPLY
    sel.nodes('actionobject') AS XmlTbl(ActObj)

通过这种方式,您可以处理多个子节点并根据需要提取它们的属性

相关文章