【问题标题】:Using MSFT SQL server XML, how to insert attributes to tags with attribute values found in a list使用 MSFT SQL 服务器 XML,如何将属性插入到列表中具有属性值的标签
【发布时间】:2018-05-09 17:48:47
【问题描述】:

我想为在名称列表中找到 @Name 值的所有元素添加一个新属性。

这是我到目前为止所得到的;它可以工作,但一次只更新一个节点。我必须为每次需要更新的事件更改“PatientNames”值。

update ListDataFormatter_Test
SET FieldDefinition.modify('
   insert attribute PlainTextPersonNotification {"True"}
   into (/Fields/Field[@Name="PatientNames"])[1]
   ')

我希望能够使用基于列表(如标准 SQL 中的“IN”子句)的单个命令对其进行更新。

update ListDataFormatter_Test
SET FieldDefinition.modify('
  insert attribute PlainTextPersonNotification {"True"}
  into (/Fields/Field[@Name in ("PatientNames", "ProviderNames", "PracticeSettingsName", "PracticeSettingsMainAddresses", "PracticeSettingsPhones")])[1]')

FieldDefinition 是 XML,其外观示例如下所示:

<Fields>
  <CalledDataFormatter Uid="9D7520C3-B507-463F-9CFD-18BDE5A74677" Prefix="PrimaryCare" />
  <Field Name="PatientNames" Layout="Name" />
  <Field Name="PatientPrimaryAddresses" Layout="Address" />
  <Field Name="PatientSecondaryAddresses" Layout="Address" />
  <Field Name="PatientDOB" Layout="Date" />
  <Field Name="PracticeSettingsName" Layout="Date" />

我得到了正确的结果,但我必须为要修改的每个 @Name 值创建一个单独的更新命令。

<Fields>
  <CalledDataFormatter Uid="9D7520C3-B507-463F-9CFD-18BDE5A74677" Prefix="PrimaryCare" />
  <Field Name="PatientNames" PlainTextPersonNotification="True" Layout="Name" />
  <Field Name="PatientPrimaryAddresses" Layout="Address" />
  <Field Name="PatientSecondaryAddresses" Layout="Address" />
  <Field Name="PatientDOB" Layout="Date" />
  <Field Name="PracticeSettingsName" PlainTextPersonNotification="True" Layout="Date" />

我的@Name 值列表现在很小,但每次会议都会增加。

【问题讨论】:

    标签: xml tsql sql-server-2012


    【解决方案1】:

    这个问题有点老了,但您可能仍需要一个解决方案。这里是FLWOR for your rescue

    DECLARE @tbl TABLE(ID INT IDENTITY, FieldDefinition XML);
    INSERT INTO @tbl VALUES
     ( '<Fields>
          <CalledDataFormatter Uid="9D7520C3-B507-463F-9CFD-18BDE5A74677" Prefix="PrimaryCare" />
          <Field Name="PatientNames" Layout="Name" />
          <Field Name="PatientPrimaryAddresses" Layout="Address" />
          <Field Name="PatientSecondaryAddresses" Layout="Address" />
          <Field Name="PatientDOB" Layout="Date" />
          <Field Name="PracticeSettingsName" Layout="Date" />
        </Fields>');
    

    --声明@Name值列表

      DECLARE @ListOfNames VARCHAR(100)='PatientNames ProviderNames PracticeSettingsName PracticeSettingsMainAddresses PracticeSettingsPhones';
    

    --使用 FLWOR 来操作你的 XML

      SELECT FieldDefinition.query(
      N'
        <Fields>
        {
            for $nd in /Fields/*
            return 
            if(local-name($nd)="Field" and contains(sql:variable("@ListOfNames"),$nd/@Name)) then
                <Field PlainTextPersonNotification="True" >{$nd/@*}</Field>
            else
                $nd
        }
        </Fields>
      ')  
      FROM @tbl; 
    

    结果

    <Fields>
      <CalledDataFormatter Uid="9D7520C3-B507-463F-9CFD-18BDE5A74677" Prefix="PrimaryCare" />
      <Field PlainTextPersonNotification="True" Name="PatientNames" Layout="Name" />
      <Field Name="PatientPrimaryAddresses" Layout="Address" />
      <Field Name="PatientSecondaryAddresses" Layout="Address" />
      <Field Name="PatientDOB" Layout="Date" />
      <Field PlainTextPersonNotification="True" Name="PracticeSettingsName" Layout="Date" />
    </Fields>
    

    简短说明

    您可以使用 FLWOR 重新构建您的 XML。我们从硬编码的&lt;Fields&gt; 开始。我们对&lt;Fields&gt;以下的所有元素使用迭代。
    如果他们的local-name()Field 并且声明的名称列表包含@Name 的值,我们将构建一个具有需求属性的新&lt;Field&gt; 元素并添加所有预先存在的属性。否则我们将原样返回元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      相关资源
      最近更新 更多