使用 XML Updategram 更新数据 (SQLXML 4.0)

适用于:SQL ServerAzure SQL 数据库

更新现有数据时,必须同时 <指定之前><之后> 的 块。 在 块之前>和之后块中指定的<元素描述了所需的更改。>< updategram 使用在 before> 块中指定的<元素 () 来标识数据库中的现有记录 () 。 after 块中<> () 的相应元素指示执行更新操作后记录的外观。 根据此信息,updategram 将创建与 after> 块匹配的< SQL 语句。 然后,Updategram 使用该语句更新数据库。

以下是 Updategram 的更新操作格式:

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
<updg:sync [mapping-schema="SampleSchema.xml"]  >  
   <updg:before>  
      <ElementName [updg:id="value"] .../>  
      [<ElementName [updg:id="value"] .../> ... ]  
   </updg:before>  
   <updg:after>  
      <ElementName [updg:id="value"] ... />  
      [<ElementName [updg:id="value"] .../> ...]  
   </updg:after>  
</updg:sync>  
</ROOT>  

<updg:before>
before> 块中的<元素标识数据库表中的现有记录。

<updg:after>
after> 块中的<元素描述在应用更新后,在 before> 块中指定的<记录应如何查找。

mapping-schema 属性标识 updategram 要使用的映射架构。 如果 updategram 指定映射架构,则之前>和之后块中指定的<元素和<属性名称必须与架构中的名称匹配。> 该映射架构将这些元素或属性名称映射到数据库表和列名称。

如果 Updategram 不指定架构,则 Updategam 将使用默认映射。 在默认映射中 <,updategram 中指定的 ElementName> 映射到数据库表,子元素或属性映射到数据库列。

before> 块中的<元素必须与数据库中的一个表行匹配。 如果元素与多个表行匹配或与任何表行不匹配,则 updategram 将返回错误并取消整个 <同步> 块。

updategram 可以包含多个 <同步> 块。 每个 <同步> 块都被视为一个事务。 每个<同步>之前和之后可以有多个<>块。>< 例如,如果要更新两个现有记录,则可以在对之前>和之后指定两<个对,每个记录一个用于更新的记录。><

使用 updg:id 属性

之前>和之后块中<指定了多个元素时,请使用 updg:id 属性标记块之前>和之后块中的<行。<><> 处理逻辑使用此信息来确定前> 块中的<哪些记录与后>块中的<哪条记录配对。

(不需要 updg:id 属性,但如果存在以下任一情况,则建议) :

  • 指定映射架构中的元素在它们上定义了 sql:key-fields 属性。

  • 为 Updategram 中的键字段提供了一个或多个特定值。

如果任一情况,updategram 将使用 sql:key-fields 中指定的键列来配对之前>块和之后块中的<元素。><

如果映射架构未通过使用 sql:key-fields) 标识 (键列,或者 updategram 正在更新键列值,则必须指定 updg:id

块之前>和之后的 块中<标识的记录不必采用相同的顺序。>< updg:id 属性强制在之前>块和之后块中指定的<元素之间关联。><

如果在前> 块中<指定一个元素,在后>块中<只指定一个相应的元素,则不需要使用 updg:id。 但是,建议仍然指定 updg:id 以避免歧义。

示例

在使用 Updategram 示例之前,请注意以下事项:

  • 大多数示例使用默认映射(即,未在 updategram 中指定任何映射架构)。 有关使用映射架构的 updategram 的更多示例,请参阅 在 SQLXML 4.0) (Updategram 中指定带批注的映射架构

  • 大多数示例使用 AdventureWorks 示例数据库。 已对该数据库中的表应用所有更新。 您可以还原 AdventureWorks 数据库。

A. 更新记录

以下 Updategram 将 AdventureWorks 数据库的 Person.Contact 表中的雇员姓氏更新为 Fuller。 Updategram 不指定任何映射架构,因此,Updategram 使用默认映射。

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
<updg:sync >  
<updg:before>  
   <Person.Contact ContactID="1" />  
</updg:before>  
<updg:after>  
   <Person.Contact LastName="Abel-Achong" />  
</updg:after>  
</updg:sync>  
</ROOT>  

before> 块中描述的<记录表示数据库中的当前记录。 updategram 使用 before> 块中指定的<所有列值来搜索记录。 在此 updategram 中 <,before> 块仅提供 ContactID 列;因此,updategram 仅使用 值来搜索记录。 如果要将 LastName 值添加到该块,则 Updategram 会同时使用 ContactID 和 LastName 值执行搜索。

在此 updategram 中 <, after> 块仅提供 LastName 列值,因为这是正在更改的唯一值。

测试 updategram
  1. 复制上面的 Updategram 模板,并将它粘贴到文本文件中。 将该文件另存为 UpdateLastName.xml。

  2. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 以执行 updategram。

    有关详细信息,请参阅 使用 ADO 执行 SQLXML 4.0 查询

B. 使用 updg:id 属性更新多个记录

在该示例中,Updategram 对 AdventureWorks 数据库中的 HumanResources.Shift 表执行两次更新:

  • 它将 7:00AM 开始的原始白班的名称从“Day”更改为“Early Morning”。

  • 它插入名为“Late Morning”的从 10:00AM 开始的新班。

在 updategram 中,updg:id 属性在前后<>块中的<元素之间创建>关联。

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
  <updg:sync >  
    <updg:before>  
       <HumanResources.Shift updg:id="x" Name="Day" />  
    </updg:before>  
    <updg:after>  
      <HumanResources.Shift updg:id="y" Name="Late Morning"   
                            StartTime="1900-01-01 10:00:00.000"  
                            EndTime="1900-01-01 18:00:00.000"  
                            ModifiedDate="2004-06-01 00:00:00.000"/>  
      <HumanResources.Shift updg:id="x" Name="Early Morning" />  
    </updg:after>  
  </updg:sync>  
</ROOT>  

请注意 updg:id 属性如何将 before> 块中的 HumanResources.Shift 元素的第一个实例与后块中的<<HumanResources.Shift 元素的第二个实例配对。><><>

测试 updategram
  1. 复制上面的 Updategram 模板,并将它粘贴到文本文件中。 将该文件另存为 UpdateMultipleRecords.xml。

  2. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 以执行 updategram。

    有关详细信息,请参阅 使用 ADO 执行 SQLXML 4.0 查询

C. 在块之前>和<之后>指定多个<块

为避免歧义,可以在示例 B 中使用多个块对前后>的多个<来编写 updategram。<><对之前><之后> 指定对是指定多个更新的一种方法,同时尽量减少混淆。 此外,如果<每个前后><>块最多指定一个元素,则不必使用 updg:id 属性。

注意

若要形成对, <after> 标记必须紧跟其对应的 <before> 标记。

在以下 updategram 中,对之前>和之后的第一个<更新日班的班次名称。>< 第二对将插入新的轮班记录。

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
  <updg:sync >  
    <updg:before>  
       <HumanResources.Shift ShiftID="1" Name="Day" />  
    </updg:before>  
    <updg:after>  
      <HumanResources.Shift Name="Early Morning" />  
    </updg:after>  
    <updg:before>  
    </updg:before>  
    <updg:after>  
      <HumanResources.Shift Name="Late Morning"   
                            StartTime="1900-01-01 10:00:00.000"  
                            EndTime="1900-01-01 18:00:00.000"  
                            ModifiedDate="2004-06-01 00:00:00.000"/>  
    </updg:after>  
  </updg:sync>  
</ROOT>  
测试 updategram
  1. 复制上面的 Updategram 模板,并将它粘贴到文本文件中。 将该文件另存为 UpdateMultipleBeforeAfter.xml。

  2. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 以执行 updategram。

    有关详细信息,请参阅 使用 ADO 执行 SQLXML 4.0 查询

D. 指定多个 <同步> 块

可以在 updategram 中指定多个 <同步> 块。 指定的每个 <同步> 块都是一个独立的事务。

在以下 updategram 中,第一个 <同步> 块更新 Sales.Customer 表中的记录。 出于简化原因,Updategram 仅指定必需的列值:标识值 (CustomerID) 和要更新的值 (SalesPersonID)。

第二个 <同步> 块将两条记录添加到 Sales.SalesOrderHeader 表。 对于该表,SalesOrderID 是 IDENTITY 类型的列。 因此,updategram 不会在每个 <Sales.SalesOrderHeader> 元素中指定 SalesOrderID 的值。

指定多个 <同步> 块很有用,因为如果第二 <个同步> 块 (事务) 未能将记录添加到 Sales.SalesOrderHeader 表,则第一个 <同步> 块仍可以更新 Sales.Customer 表中的客户记录。

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
  <updg:sync >  
    <updg:before>  
      <Sales.Customer CustomerID="1" SalesPersonID="280" />  
    </updg:before>  
    <updg:after>  
      <Sales.Customer CustomerID="1" SalesPersonID="283" />  
    </updg:after>  
  </updg:sync>  
  <updg:sync >  
    <updg:before>  
    </updg:before>  
    <updg:after>  
   <Sales.SalesOrderHeader   
             CustomerID="1"  
             RevisionNumber="1"  
             OrderDate="2004-07-01 00:00:00.000"  
             DueDate="2004-07-13 00:00:00.000"  
             OnlineOrderFlag="0"  
             ContactID="378"  
             BillToAddressID="985"  
             ShipToAddressID="985"  
             ShipMethodID="5"  
             SubTotal="24643.9362"  
             TaxAmt="1971.5149"  
             Freight="616.0984"  
             rowguid="01010101-2222-3333-4444-556677889900"  
             ModifiedDate="2004-07-08 00:00:00.000" />  
   <Sales.SalesOrderHeader  
             CustomerID="1"  
             RevisionNumber="1"  
             OrderDate="2004-07-01 00:00:00.000"  
             DueDate="2004-07-13 00:00:00.000"  
             OnlineOrderFlag="0"  
             ContactID="378"  
             BillToAddressID="985"  
             ShipToAddressID="985"  
             ShipMethodID="5"  
             SubTotal="1000.0000"  
             TaxAmt="0.0000"  
             Freight="0.0000"  
             rowguid="10101010-2222-3333-4444-556677889900"  
             ModifiedDate="2004-07-09 00:00:00.000" />  
    </updg:after>  
  </updg:sync>  
</ROOT>  
测试 updategram
  1. 复制上面的 Updategram 模板,并将它粘贴到文本文件中。 将文件另存为 UpdateMultipleSyncs.xml。

  2. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 以执行 updategram。

    有关详细信息,请参阅 使用 ADO 执行 SQLXML 4.0 查询

E. 使用映射架构

在此示例中,updategram 使用 mapping-schema 属性指定映射架构 。 (没有默认映射;就是说,由映射架构提供所需的映射,将 Updategram 中的元素和属性映射到数据库表和列。)

在 Updategram 中指定的元素和属性将引用映射架构中的元素和属性。

以下 XSD 映射架构具有<映射到数据库中的 Sales.Customer、Sales.SalesOrderHeader 和 Sales.SalesOrderDetail 表的 Customer><、Order><OD> 元素。

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
            xmlns:sql="urn:schemas-microsoft-com:mapping-schema">  
<xsd:annotation>  
  <xsd:appinfo>  
    <sql:relationship name="CustomerOrder"  
          parent="Sales.Customer"  
          parent-key="CustomerID"  
          child="Sales.SalesOrderHeader"  
          child-key="CustomerID" />  
  
    <sql:relationship name="OrderOD"  
          parent="Sales.SalesOrderHeader"  
          parent-key="SalesOrderID"  
          child="Sales.SalesOrderDetail"  
          child-key="SalesOrderID" />  
  </xsd:appinfo>  
</xsd:annotation>  
  
  <xsd:element name="Customer" sql:relation="Sales.Customer" >  
   <xsd:complexType>  
     <xsd:sequence>  
        <xsd:element name="Order"   
                     sql:relation="Sales.SalesOrderHeader"  
                     sql:relationship="CustomerOrder" >  
           <xsd:complexType>  
              <xsd:sequence>  
                <xsd:element name="OD"   
                             sql:relation="Sales.SalesOrderDetail"  
                             sql:relationship="OrderOD" >  
                 <xsd:complexType>  
                  <xsd:attribute name="SalesOrderID" type="xsd:integer" />  
                  <xsd:attribute name="ProductID" type="xsd:integer" />  
                  <xsd:attribute name="UnitPrice" type="xsd:decimal" />  
                  <xsd:attribute name="OrderQty" type="xsd:integer" />  
                  <xsd:attribute name="UnitPriceDiscount" type="xsd:decimal" />   
                 </xsd:complexType>  
                </xsd:element>  
              </xsd:sequence>  
              <xsd:attribute name="CustomerID" type="xsd:string" />  
              <xsd:attribute name="SalesOrderID" type="xsd:integer" />  
              <xsd:attribute name="OrderDate" type="xsd:date" />  
           </xsd:complexType>  
        </xsd:element>  
      </xsd:sequence>  
      <xsd:attribute name="CustomerID"   type="xsd:string" />   
    </xsd:complexType>  
  </xsd:element>  
</xsd:schema>  

以下 Updategram 指定该映射架构 (UpdategramMappingSchema.xml)。 该 Updategram 在 Sales.SalesOrderDetail 表中为特定顺序添加顺序细节项。 updategram 包括嵌套元素:嵌套在 Order> 元素内的<OD> 元素。< 在映射架构中指定了这两个元素之间的主键/外键关系。

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
  <updg:sync mapping-schema="UpdategramMappingSchema.xml" >  
    <updg:before>  
       <Order SalesOrderID="43659" />  
    </updg:before>  
    <updg:after>  
      <Order SalesOrderID="43659" >  
          <OD ProductID="776" UnitPrice="2329.0000"  
              OrderQty="2" UnitPriceDiscount="0.0" />  
      </Order>  
    </updg:after>  
  </updg:sync>  
</ROOT>  
测试 updategram
  1. 复制上面的映射架构,并将它粘贴到文本文件中。 将该文件另存为 UpdategramMappingSchema.xml。

  2. 复制上面的 Updategram 模板,并将它粘贴到文本文件中。 在用于保存映射架构 (UpdategramMappingSchema.xml) 的相同文件夹中将该文件另存为 UpdateWithMappingSchema.xml。

  3. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 以执行 updategram。

    有关详细信息,请参阅 使用 ADO 执行 SQLXML 4.0 查询

有关使用映射架构的 updategram 的更多示例,请参阅 在 SQLXML 4.0) (Updategram 中指定带批注的映射架构

F. 将 IDREFS 属性与映射架构一起使用

该示例说明 Updategram 如何在映射架构中使用 IDREFS 属性以更新多个表中的记录。 对于该示例,假定数据库由以下表组成:

  • Student(StudentID, LastName)

  • Course(CourseID, CourseName)

  • Enrollment(StudentID, CourseID)

由于学生可以注册参加很多课程,而且一种课程可以有很多学生,因此需要用第三个表 Enrollment 表以表示该 M:N 关系。

以下 XSD 映射架构使用 Student>、Course 和 Enrollment 元素提供表的< XML 视图。<><> 映射架构中的 IDREFS 属性指定这些元素之间的关系。 Course> 元素上的<StudentIDList 属性是引用 Enrollment 表中 StudentID 列的 IDREFS 类型属性。 同样,Student> 元素上的<EnrollmentedIn 属性是引用 Enrollment 表中的 CourseID 列的 IDREFS 类型属性。

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
            xmlns:sql="urn:schemas-microsoft-com:mapping-schema">  
<xsd:annotation>  
  <xsd:appinfo>  
    <sql:relationship name="StudentEnrollment"  
          parent="Student"  
          parent-key="StudentID"  
          child="Enrollment"  
          child-key="StudentID" />  
  
    <sql:relationship name="CourseEnrollment"  
          parent="Course"  
          parent-key="CourseID"  
          child="Enrollment"  
          child-key="CourseID" />  
  </xsd:appinfo>  
</xsd:annotation>  
  
  <xsd:element name="Course" sql:relation="Course"   
                             sql:key-fields="CourseID" >  
    <xsd:complexType>  
    <xsd:attribute name="CourseID"  type="xsd:string" />   
    <xsd:attribute name="CourseName"   type="xsd:string" />   
    <xsd:attribute name="StudentIDList" sql:relation="Enrollment"  
                 sql:field="StudentID"  
                 sql:relationship="CourseEnrollment"   
                                     type="xsd:IDREFS" />  
  
    </xsd:complexType>  
  </xsd:element>  
  <xsd:element name="Student" sql:relation="Student" >  
    <xsd:complexType>  
    <xsd:attribute name="StudentID"  type="xsd:string" />   
    <xsd:attribute name="LastName"   type="xsd:string" />   
    <xsd:attribute name="EnrolledIn" sql:relation="Enrollment"  
                 sql:field="CourseID"  
                 sql:relationship="StudentEnrollment"   
                                     type="xsd:IDREFS" />  
    </xsd:complexType>  
  </xsd:element>  
</xsd:schema>  

一旦在 Updategram 中指定该架构,并在 Course 表中插入记录,则 Updategram 将在 Course 表中插入新的课程记录。 如果为 StudentIDList 属性指定一个或多个新学生 ID,则 Updategram 还将在 Enrollment 表中为每个新学生插入记录。 该 Updategram 将确保不向 Enrollment 表添加重复项。

测试 updategram
  1. 在虚拟根目录中所指定的数据库内创建这些表:

    CREATE TABLE Student(StudentID varchar(10) primary key,   
                         LastName varchar(25))  
    CREATE TABLE Course(CourseID varchar(10) primary key,   
                        CourseName varchar(25))  
    CREATE TABLE Enrollment(StudentID varchar(10)   
                                      references Student(StudentID),  
                           CourseID varchar(10)   
                                      references Course(CourseID))  
    
  2. 添加以下示例数据:

    INSERT INTO Student VALUES ('S1','Davoli')  
    INSERT INTO Student VALUES ('S2','Fuller')  
    
    INSERT INTO Course VALUES  ('CS101', 'C Programming')  
    INSERT INTO Course VALUES  ('CS102', 'Understanding XML')  
    
    INSERT INTO Enrollment VALUES ('S1', 'CS101')  
    INSERT INTO Enrollment VALUES ('S1', 'CS102')  
    
  3. 复制上面的映射架构,并将它粘贴到文本文件中。 将该文件另存为 SampleSchema.xml。

  4. 将 Updategram (SampleUpdategram) 保存到上一步中用于保存映射架构的相同文件夹中。 (该 Updategram 从 CS102 课程中删除 StudentID="1" 的学生。)

    <ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
      <updg:sync mapping-schema="SampleSchema.xml" >  
        <updg:before>  
            <Student updg:id="x" StudentID="S1" LastName="Davolio"  
                                 EnrolledIn="CS101 CS102" />  
        </updg:before>  
        <updg:after >  
            <Student updg:id="x" StudentID="S1" LastName="Davolio"  
                                 EnrolledIn="CS101" />  
        </updg:after>  
      </updg:sync>  
    </ROOT>  
    
  5. 创建并使用 SQLXML 4.0 测试脚本 (Sqlxml4test.vbs) 以执行 updategram。

    有关详细信息,请参阅 使用 ADO 执行 SQLXML 4.0 查询

  6. 按照前面描述的步骤,保存并执行以下 Updategram。 该 Updategram 在 Enrollment 表中添加记录,从而将 StudentID="1" 的学生重新添加到 CS102 课程中。

    <ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
      <updg:sync mapping-schema="SampleSchema.xml" >  
        <updg:before>  
            <Student updg:id="x" StudentID="S1" LastName="Davolio"  
                                 EnrolledIn="CS101" />  
        </updg:before>  
        <updg:after >  
            <Student updg:id="x" StudentID="S1" LastName="Davolio"  
                                 EnrolledIn="CS101 CS102" />  
        </updg:after>  
      </updg:sync>  
    </ROOT>  
    
  7. 按照前面描述的步骤,保存并执行下一个 Updategram。 该 Updategram 插入三个新学生,并将他们注册到 CS101 课程。 同样,IDREFS 关系将在 Enrollment 表中插入记录。

    <ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
      <updg:sync mapping-schema="SampleSchema.xml" >  
        <updg:before>  
           <Course updg:id="y" CourseID="CS101"   
                               CourseName="C Programming" />  
        </updg:before>  
        <updg:after >  
           <Student updg:id="x1" StudentID="S3" LastName="Leverling" />  
           <Student updg:id="x2" StudentID="S4" LastName="Pecock" />  
           <Student updg:id="x3" StudentID="S5" LastName="Buchanan" />  
           <Course updg:id="y" CourseID="CS101"  
                               CourseName="C Programming"  
                               StudentIDList="S3 S4 S5" />  
        </updg:after>  
      </updg:sync>  
    </ROOT>  
    

这是等效的 XDR 架构:

<?xml version="1.0" ?>  
<Schema xmlns="urn:schemas-microsoft-com:xml-data"  
        xmlns:dt="urn:schemas-microsoft-com:datatypes"  
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <ElementType name="Enrollment" sql:relation="Enrollment" sql:key-fields="StudentID CourseID">  
    <AttributeType name="StudentID" dt:type="id" />  
    <AttributeType name="CourseID" dt:type="id" />  
  
    <attribute type="StudentID" />  
    <attribute type="CourseID" />  
  </ElementType>  
  <ElementType name="Course" sql:relation="Course" sql:key-fields="CourseID">  
    <AttributeType name="CourseID" dt:type="id" />  
    <AttributeType name="CourseName" />  
  
    <attribute type="CourseID" />  
    <attribute type="CourseName" />  
  
    <AttributeType name="StudentIDList" dt:type="idrefs" />  
    <attribute type="StudentIDList" sql:relation="Enrollment" sql:field="StudentID" >  
        <sql:relationship  
                key-relation="Course"  
                key="CourseID"  
                foreign-relation="Enrollment"  
                foreign-key="CourseID" />  
    </attribute>  
  
  </ElementType>  
  <ElementType name="Student" sql:relation="Student">  
    <AttributeType name="StudentID" dt:type="id" />  
     <AttributeType name="LastName" />  
  
    <attribute type="StudentID" />  
    <attribute type="LastName" />  
  
    <AttributeType name="EnrolledIn" dt:type="idrefs" />  
    <attribute type="EnrolledIn" sql:relation="Enrollment" sql:field="CourseID" >  
        <sql:relationship  
                key-relation="Student"  
                key="StudentID"  
                foreign-relation="Enrollment"  
                foreign-key="StudentID" />  
    </attribute>  
  
    <element type="Enrollment" sql:relation="Enrollment" >  
        <sql:relationship key-relation="Student"  
                          key="StudentID"  
                          foreign-relation="Enrollment"  
                          foreign-key="StudentID" />  
    </element>  
  </ElementType>  
  
</Schema>  

有关使用映射架构的 updategram 的更多示例,请参阅 在 SQLXML 4.0) (Updategram 中指定带批注的映射架构

另请参阅

updategram 的安全注意事项 (SQLXML 4.0)