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

更新现有数据时,必须同时指定块前后的两<>>者<。 块前后<>>指定的<元素描述所需的更改。 updategram 使用在前>块中指定的<元素来标识数据库中的现有记录。 后>块中的<相应元素指示记录在执行更新作后应如何查找。 从此信息中,updategram 将创建一个与后>块匹配的< 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>
前>块中的<元素标识数据库表中的现有记录。

<updg:after>
后>块中的<元素描述了在块之前<>指定的记录应如何应用更新。

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

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

块>中的<元素必须与数据库中只有一个表行匹配。 如果元素匹配多个表行或与任何表行不匹配,则 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)。

  • 大多数示例都使用 AdventureWorks 示例数据库。 所有更新都应用于此数据库中的表。 可以还原 AdventureWorks 数据库。

答: 更新记录

以下 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>  

块中所述<>的记录表示数据库中的当前记录。 updategram 使用前>块中指定的<所有列值来搜索记录。 在此 updategram 中 <,前> 一个块仅提供 ContactID 列;因此,updategram 仅使用值来搜索记录。 如果要将 LastName 值添加到此块,updategram 将使用 ContactID 和 LastName 值进行搜索。

在此 updategram 中 <,后> 块仅提供 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:00 开始的原始日班次的名称从“天”更改为“清晨”。

  • 它插入一个名为“深夜”的新班次,从上午 10:00 开始。

在 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属性。

注释

若要形成对, <后> 一个标记必须紧跟其对应的 <标记之前>

在以下 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 中指定的元素和属性是指映射架构中的元素和属性。

以下 XSD 映射架构具有<>客户<订单><OD> 元素,这些元素映射到数据库中的 Sales.Customer、Sales.SalesOrderHeader 和 Sales.SalesOrderDetail 表。

<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>  

此映射架构(UpdategramMappingSchema.xml)在以下 updategram 中指定。 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 模板并将其粘贴到文本文件中。 将文件另存为 UpdateWithMappingSchema.xml,与用于保存映射架构(UpdategramMappingSchema.xml)相同的文件夹中。

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

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

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

F. 将映射架构与 IDREFS 属性配合使用

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

  • Student(StudentID、LastName)

  • Course(CourseID、CourseName)

  • Enrollment(StudentID、CourseID)

由于学生可以注册许多课程,并且一门课程可以有多个学生,因此需要第三个表(即注册表)来表示此 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 还会在每个新学生的注册表中插入一条记录。 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)保存在用于在上一步中保存映射架构的同一文件夹中。 (此更新报从 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 通过在注册表中添加记录,将 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,如前面的步骤中所述。 此更新报插入三名新学生,并在 CS101 课程中注册。 同样,IDREFS 关系在注册表中插入记录。

    <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 安全注意事项 (SQLXML 4.0)