首页 > 解决方案 > 使用 MSFT SQL 服务器 XML,如何将属性插入到列表中具有属性值的标签

问题描述

我想为在名称列表中找到 @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 值列表现在很小,但每次会议都在增长。

标签: xmltsqlsql-server-2012

解决方案


这个问题有点老了,但你可能仍然需要一个解决方案。这是为您解救的 FLWOR

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。我们从硬编码开始<Fields>。我们对下面的所有元素使用迭代<Fields>
如果它们local-name()Field并且声明的名称列表包含的值,@Name我们构建一个<Field>具有需要属性的新元素并添加所有预先存在的属性。否则,我们将原样返回元素。


推荐阅读