Modifying Data with Updategrams

I explained in previous chapters how you can use templates to retrieve data over ADO or HTTP connections. However, retrieving data solves only half the problem. We also need a way to modify data by updating records, deleting them, or adding new ones. For example, the Northwind Traders Web site might allow users to not only view the products available, but also place orders by adding records to the Orders and Order Details tables. Or Northwind Traders could use an intranet-based application to update employee records. Updategrams give developers an XML-based approach to data modification, in much the same way that templates allow you an XML-based way to retrieve data. An updategram is an XML document containing a before and after image of the data you want to modify, which you can submit to SQL Server much as you submit a template.

Anatomy of an Updategram

An updategram is based on the xml-updategram namespace and contains one or more sync elements. Each sync element represents a transactional unit of database modifications. Sync elements contain at least one pair of before and after elements representing an individual insert, update, or delete operation. For example, the following updategram could be used to change the HomePhone field in the Employees table for employee number 1:

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Employees Employee/>         </updg:before>         <updg:after>             <Employees HomePhone="555-112233"/>         </updg:after>     </updg:sync> </employeeupdate> 

This updategram can be viewed in the UpdateEmployee.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. You can execute it by opening the Update Employee shortcut in the Demos\Chapter8 folder. If you include more than one sync element in an updategram, each sync element is treated as a transaction. In other words, if an error causes an update to fail, all the other updates in that sync element will also fail. The updates in other sync elements, however, will be unaffected.

Each element in the before element must identify only a single record for modification. In other words, you can't specify a before element that results in multiple records being updated. For this reason, the elements in the before element usually include either the primary key value of the row to be modified or multiple columns that represent a unique combination.

Mapping Data in an Updategram

You can map the XML data in an updategram to SQL Server tables and columns in two ways: you can use default mapping or a mapping schema.

Using the Default Mapping

The easiest approach to mapping XML data in an updategram is to use the default (or intrinsic) mapping, which assumes that the top-level tag in a before or after element is named after the table it represents, and that the columns in that table are represented by attributes or subelements. For example, the EmployeeID column in the Employees table could be mapped using either of the following XML elements:

 <Employees Employee/> 

or

 <Employees>     <EmployeeID>1</EmployeeID> </Employees> 

When more than one column is specified, you can use a mixture of attribute-centric and element-centric mappings, as shown in this sample code:

 <Employees Employee>     <HomePhone>555-112233</HomePhone> </Employees> 

If a table name contains an illegal character (such as a space) for an XML element name, you must use the four-digit hexadecimal UCS-2 value for that character to encode it. For example, the following XML could be used to represent the OrderID column in the Order Details table:

 <Order_x0020_Details Order/> 

Using a Mapping Schema

An alternative approach to mapping data in an updategram to tables and columns in the database is to specify a mapping schema. I described how to use mapping schemas to map XML elements and attributes to data in the database in Chapter 6. To specify a mapping schema in an updategram, you use the mapping-schema annotation in a sync element, as shown in this example:

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync updg:mapping-schema="EmployeeSchema.xml">         <updg:before>             <Employee Emp/>         </updg:before>         <updg:after>             <Employee Phone="555-112233"/>         </updg:after>     </updg:sync> </employeeupdate> 

You can find this updategram in the UpdateEmployeesSchema.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. The mapping schema referenced (in this case EmployeeSchema.xml) should contain the information necessary to map the elements in the updategram to data in the database. For example, the updategram could be mapped to the Employees table using the following schema:

 <?xml version="1.0"?> <Schema xmlns="urn:schemas-microsoft-com:xml-data"      xmlns:sql="urn:schemas-microsoft-com:xml-sql">     <ElementType name="Employee" sql:relation="Employees">         <AttributeType name="EmpID"/>         <AttributeType name="Phone"/>         <attribute type="EmpID" sql:field="EmployeeID"/>         <attribute type="Phone" sql:field="HomePhone"/>     </ElementType> </Schema> 

This schema is also available in the EmployeeSchema.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. You can execute the updategram that uses this schema by opening the Update Employees (Schema) shortcut in the Demos\Chapter8 folder. This schema maps the Employee element to the Employees table and the EmpID and Phone attributes to the EmployeeID and HomePhone columns, respectively.

Handling NULLs in an Updategram

Databases often use NULL to indicate that the value of a field is unknown. You can use the nullvalue attribute to retrieve or set a NULL value in an updategram. The nullvalue attribute is used in the sync element to assign a placeholder string used to represent NULL. You can then use this placeholder in the updategram to identify a column containing a NULL value or to set a column value to NULL. For example, the following updategram sets an employee's HomePhone field to NULL:

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync updg:nullvalue="NoPhone">         <updg:before>             <Employees Employee/>         </updg:before>         <updg:after>             <Employees HomePhone="NoPhone"/>         </updg:after>     </updg:sync> </employeeupdate> 

This updategram is also available in the UpdateEmployeesNull.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. You can execute it by opening the Update Employees (NULL) shortcut in the Demos\Chapter8 folder.

Using Parameters in an Updategram

Because an updategram is essentially a specialized template, you'd expect to be able to pass parameters to an updategram in much the same way that you pass them to a template. But in fact, you need to observe a slight difference in the syntax when you're passing parameters to an updategram, which you may spot in this example:

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:header>         <updg:param name="EmployeeID"/>         <updg:param name="HomePhone"/>     </updg:header>     <updg:sync>         <updg:before>             <Employees Employee/>         </updg:before>         <updg:after>             <Employees HomePhone="$HomePhone"/>         </updg:after>     </updg:sync> </employeeupdate> 

The only difference between using parameters in an updategram and using parameters in a template (in case you didn't spot it) is that parameter placeholders in an updategram are prefixed by a dollar ($) symbol instead of the at (@) symbol used in templates. You can use parameters in an updategram either to identify the rows to be modified (by specifying the parameter in the before element) or to assign a new value to a column (by specifying the parameter in the after element).

Passing NULL as a Parameter

You can pass NULL as a parameter to an updategram by specifying the nullvalue attribute in the header element. The nullvalue attribute is used to assign a placeholder value for NULL, just as when that attribute is specified in the sync element. To pass NULL to the updategram, simply pass the placeholder string; the updategram will interpret it as NULL.

One potential gotcha here is that when using the nullvalue attribute in the header element, you should not specify a namespace qualifier (such as updg:) as you do when using the nullvalue attribute in the sync element.

The following example shows an updategram that uses two parameters. If you pass a value of NoPhone to the updategram, NULL is inserted into the HomePhone column of the specified employee.

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:header nullvalue="NoPhone">         <updg:param name="EmployeeID"/>         <updg:param name="HomePhone"/>     </updg:header>     <updg:sync>         <updg:before>             <Employees Employee/>         </updg:before>         <updg:after>             <Employees HomePhone="$HomePhone"/>         </updg:after>     </updg:sync> </employeeupdate> 

You can also find this updategram in the UpdateEmployeesParam.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. You can execute it by opening the Update Employees (Parameter) shortcut in the Demos\Chapter8 folder.

Updating Multiple Rows

I told you earlier in this chapter that each element in the before element can identify only a single row. This restriction means that to update multiple rows, you must include an element for each row you want to modify.

Using the id Attribute

In addition to listing the before and after elements, you must provide SQL Server with a means of matching the before elements to their corresponding after elements. You can do this in one of two ways: by referencing a mapping schema in which the key-fields annotation is used to identify the primary key of the table being updated (and include the primary key in the before element), or by specifying the id attribute in the updategram. I explained key-fields annotation in Chapter 6, so I'll focus here on the id attribute.

You use the id attribute to specify a unique string value to match a before element with its corresponding after element. For example, the following updategram modifies two records. We use the id attribute to match the required modification in the after element with the row identified in the before element.

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Employees updg: Employee/>             <Employees updg: Employee/>         </updg:before>         <updg:after>             <Employees updg: HomePhone="555-332211"/>             <Employees updg: HomePhone="555-112233"/>         </updg:after>     </updg:sync> </employeeupdate> 

This updategram can be viewed in the UpdateEmployeesMultiRow.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. You can execute it by opening the Update Employees (Multiple Rows) shortcut in the Demos\Chapter8 folder. Because you use the id attribute to match the before and after elements, the order of appearance of the elements in the code is unimportant. The updategram sets the HomePhone field for employee 1 to 555-112233 while setting the same field for employee 2 to 555-332211.

Using Multiple before and after Elements

You can also avoid ambiguity by using multiple before and after elements in an updategram. If you specify only one element in each before and after element pair, you can avoid having to specify an id attribute. For example, you could use the following updategram to change the HomePhone field for employees 1 and 2:

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Employees Employee/>         </updg:before>         <updg:after>             <Employees HomePhone="555-112233"/>         </updg:after>         <updg:before>             <Employees Employee/>         </updg:before>         <updg:after>             <Employees HomePhone="555-332211"/>         </updg:after>     </updg:sync> </employeeupdate> 

You can view this updategram in the UpdateEmployeesMultiRow2.xml file in the Demos\Chapter8\Updategrams folder on the companion CD.

Updategram Results

When a client application executes an updategram, the result is returned as an XML document. In most cases, the document is simply the empty root element that was specified in the updategram. For example, the expected result of the employeeupdate updategram shown earlier would be this code:

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram"> </employeeupdate> 

Updategram Error Messages

If any errors occur during the execution of the updategram, they're returned as an MSSQLError processing instruction, as shown here:

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <?MSSQLError HResult="0x80004005"          Source="Microsoft XML Extensions to SQL Server"         Description="All updategram nodes with siblings must have ids,             either user-specified ones or mapping schema-based key              field id"?> </employeeupdate > 

Applying a Style Sheet

You can apply an XSL style sheet to the updategram results the same way that you would for a template. A style sheet can be applied on the server by specifying the xsl attribute (defined in the XML-SQL namespace) in the root element of the updategram, as shown here:

 <?xml version="1.0"?> <employeeupdate xmlns:updg="urn:schemas-microsoft-com:xml-updategram"     xmlns:sql="urn:schemas-microsoft-com:xml-sql"     sql:xsl="Results.xsl">     <updg:sync>         <updg:before>             <Employees Employee/>         </updg:before>         <updg:after>             <Employees Lastname="Malcolm"/>         </updg:after>     </updg:sync> </employeeupdate> 

This updategram is also available in the UpdateEmployeeName.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. You can execute it by opening the Update Employee (XSL) shortcut in the Demos\Chapter8 folder. This capability allows you to use updategrams in Web sites, while providing a suitable HTML result page when data has been modified or when an error has occurred.

Inserting Rows with an Updategram

You can use an updategram to insert data into the database. For example, you could build an e-commerce site that uses templates to allow customers to view the product data and updategrams to add customer orders to the Orders and Order Details tables. When you're using an updategram to insert data, you need to specify an empty before element, with the data to be inserted in the corresponding after element. For example, the following updategram could be used to add a row to the Order Details table. (Because the Northwind database contains a referential constraint between Orders and Order Details, this example assumes that an order with an OrderID of 10248 has already been inserted into the Orders table.)

 <?xml version="1.0"?> <neworder xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>         </updg:before>         <updg:after>         <Order_x0020_Details Order Product             UnitPrice="$10.99" Quantity="1" Discount="0"/>         </updg:after>     </updg:sync> </neworder> 

You can view this updategram in the InsertOrderDetail.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. You can execute it by opening the Insert Order Details shortcut in the Demos\Chapter8 folder.

Currency values, such as the UnitPrice column in the Order Details table, must either be mapped in a schema using the dt:type attribute with a value of fixed.14.4, or prefixed with a dollar ($) symbol, as shown in the preceding example. Because parameter values in an updategram are also prefixed with a dollar symbol, the only way to pass a currency parameter is to map the data using a mapping schema.

Inserting Multiple Rows

To insert multiple rows into the same table, you can simply specify multiple XML elements in the after element. For example, the following updategram inserts two rows into the Order Details table. (Again, the example assumes that an order with an order ID of 10248 has previously been inserted in the Orders table.)

 <?xml version="1.0"?> <neworder xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>         </updg:before>         <updg:after> 
             <Order_x0020_Details Order Product                 UnitPrice="$10.99" Quantity="1"                 Discount="0"/>             <Order_x0020_Details Order Product                 UnitPrice="$11.99" Quantity="2"                 Discount="0"/>         </updg:after>     </updg:sync> </neworder> 

This updategram is also available in the InsertMultipleOrderDetail.xml file in the Demos\Chapter8\Updategrams folder on the companion CD.

Using an IDENTITY Column Value

IDENTITY columns are automatically assigned a value by SQL Server. However, sometimes you need to know what value SQL Server has assigned in a primary key table (such as Orders) so that you can insert the same value for related rows in a foreign key table (such as Order Details). You can obtain an IDENTITY value using the at-identity attribute. This attribute allows you to use the same updategram to insert data into a primary key table that has an IDENTITY column and a foreign key table that references the primary key. For example, the following updategram would insert data into the Orders and Order Details tables:

 <?xml version="1.0"?> <neworder xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>         </updg:before>         <updg:after>             <Orders updg:at-identity="newID" Customer                  Employee OrderDate="01/01/2001"/>             <Order_x0020_Details Order Product                 UnitPrice="$10.99" Quantity="1"                 Discount="0"/>             <Order_x0020_Details Order Product                 UnitPrice="$12.99" Quantity="2"                 Discount="0"/>         </updg:after>     </updg:sync> </neworder> 

Notice that the at-identity attribute is specified in the element representing the Orders table (which contains the IDENTITY column). A placeholder value is assigned, in this case newID, which can then be used elsewhere in the updategram to represent the IDENTITY value inserted into the Orders table. The newID placeholder is assigned to the OrderID attribute in the Order Details table for both the added Order Details records.

Returning the IDENTITY Value to the Client

Of course, if this were a real e-commerce application, you'd want to return the IDENTITY value to the browser so that the customer would know the OrderID assigned to his order. To retrieve the IDENTITY value, you can add a returnid attribute to the after element and specify the placeholder name for the IDENTITY column as its value. This process is shown in the following updategram:

 <?xml version="1.0"?> <neworder xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>         </updg:before>         <updg:after updg:return>             <Orders updg:at-identity="newID" Customer                  Employee OrderDate="01/01/2001"/>             <Order_x0020_Details Order Product                 UnitPrice="$10.99" Quantity="1"                 Discount="0"/>             <Order_x0020_Details Order Product                 UnitPrice="$12.99" Quantity="2"                 Discount="0"/>         </updg:after>     </updg:sync> </neworder> 

This updategram can be viewed in the InsertOrder.xml file in the Demos\ Chapter8\Updategrams folder on the companion CD. When you execute this updategram, the value represented by the newID placeholder is returned as an element in the resulting XML document. For example, suppose the value 11088 was generated as an IDENTITY value. The following XML document would be returned:

 <?xml  version="1.0"?> <neworder xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <returnid>         <newID>11088</newID>     </returnid> </neworder> 

Of course, in a Web environment, a style sheet could be applied to the updategram results and the order ID would be displayed in a suitable format.

Generating a Globally Unique Identifier (GUID)

Many applications use Globally Unique Identifiers (or GUIDs) as unique values to identify a business entity (such as a customer or product). GUIDs are unique 16-byte values such as 6F9619FF-8B86-D011-B42D-00C04FC964FF. SQL Server supports the uniqueidentifier data type, which allows GUIDs to be stored in a SQL Server database column.

In an ordinary INSERT statement, you can use the NEWID() function to generate a GUID. However, in an updategram, you must use the guid attribute to generate a GUID for use anywhere within a sync block. As with the at-identity attribute, the guid attribute specifies a placeholder value representing the new GUID. For example, you could use the following updategram to insert rows into a SpecialOrder table and a SpecialOrderDetail table, in which a GUID is used to identify an order. (Note that these tables don't actually exist in the Northwind database.)

 <NewSpecialOrder      xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>         </updg:before>         <updg:after>             <SpecialOrder updg:gu>                 <OrderID>NewGUID</OrderID>                 <OrderDate>01/01/2001</OrderDate>             </SpecialOrder>             <SpecialOrderDetail>                 <OrderID>NewGUID</OrderID>                 <ProductID>1</ProductID>                 <Quantity>2</Quantity>             </SpecialOrderDetail>         </updg:after>     </updg:sync> </NewSpecialOrder> 

Deleting Data with an Updategram

To delete rows from a table with an updategram, you essentially do the opposite of an INSERT operation. The row (or rows) to be deleted must be identified in the before element, with no corresponding elements in the after element. The principal difference in process to remember is that each element in the before element must uniquely identify a single row in the database; in an updategram, there's no equivalent of a wildcard delete operation (in which multiple records can be deleted based on a single criterion).

For example, the following updategram could be used to delete an employee record from the database:

 <?xml version="1.0"?> <DeleteEmployee xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Employees Employee/>         </updg:before>         <updg:after>         </updg:after>     </updg:sync> </DeleteEmployee> 

To delete multiple rows, specify multiple elements in the before element, as the following code shows:

 <?xml version="1.0"?> <DeleteEmployee xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Employees Employee/>             <Employees Employee/>         </updg:before>         <updg:after>         </updg:after>     </updg:sync> </DeleteEmployee> 

Updategrams don't support cascading deletes (the capacity to delete related records in other tables) unless the ON DELETE CASCADE option was specified when the table containing the data was created. For more information about the SQL Server 2000 support for cascading referential integrity, refer to SQL Server Books Online.

Updategrams and Concurrency

When a database is accessed by many users, you can encounter concurrency issues (such as excessive locking) as multiple users attempt to access the same data. Many database applications adopt different strategies to deal with locking-the most common approaches being optimistic locking and pessimistic locking. Optimistic locking takes its name from the fact that the application doesn't lock any data until an update takes place. (In other words, you're optimistic that no other user will change the data in the time between your access of the data and your update of the data.) This strategy results in much shorter lock times and better throughput but means that any data you retrieve can be updated (or even deleted) by another user while you're still working with it. Pessimistic locking takes the opposite approach; the application locks all data as soon as someone accesses it. (In other words, you're pessimistically assuming that some other user will attempt to change the data before you're finished with it.) This strategy prevents many concurrency errors but increases the amount of time data is locked, and therefore can degrade performance. Updategrams are based on an optimistic concurrency model, which means that other users can access the data affected by your updategram while it's in progress. However, you can control the updategram's behavior when this happens by using one of three levels of protection-low concurrency protection, intermediate concurrency protection, or high concurrency protection.

Low Concurrency Protection

You can use the lowest level of protection by simply specifying the primary key (or some unique combination identifying a single row) in the before element. For example, consider the following updategram:

 <?xml version="1.0"?> <UpdateShipper xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Shippers Shipper/>         </updg:before>         <updg:after>             <Shippers Phone="(503) 555-1122"/>         </updg:after>     </updg:sync> </UpdateShipper> 

When this updategram is executed, SQL Server retrieves the row identified in the before element and then updates the Phone column for that record. The equivalent Transact-SQL statement for the after element in this updategram would be the following:

 UPDATE Shippers SET Phone='(503) 555-1122' WHERE ShipperID=1 

The update happens regardless of any other activity in the database, even if another user changes the same field in the same record between the retrieval and the update. Effectively, this is what's known as a blind update because you update the record even though you can't see changes made by other users. This level of protection provides great performance but could lead to some unexpected results.

Intermediate Concurrency Protection

You can apply the next level of protection by specifying the column you're changing in the before element. This level ensures that the update takes place only if at the time of the update the field being updated still has the same value specified in the before element. For example, you could use the following updategram to update the shipper's phone number:

 <?xml version="1.0"?> <UpdateShipper xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Shippers Shipper Phone="(503) 555-9831"/>         </updg:before>         <updg:after>             <Shippers Phone="(503) 555-1122"/>         </updg:after>     </updg:sync> </UpdateShipper> 

In this case, the shipper record is updated only if the Phone field value remains (503) 555-9831 throughout the entire updategram operation. The equivalent Transact-SQL statement for the after element is the following:

 UPDATE Shippers SET Phone='(503) 555-1122' WHERE ShipperID=1 AND Phone='(503) 555-9831' 

If another user updates the Phone field for this record between the execution of the before element and the execution of the after element, the updategram returns an error message. Of course, any concurrent updates to the other field in the record (CompanyName) have no effect on your update operation and will be ignored, and the end result will be a merge of all the concurrent update operations.

High Concurrency Protection

The highest level of protection allows the update to take place only if the record hasn't been modified at all between the before and after element executions. You can achieve this level in one of two ways: you can specify all the fields in the before element, or you can make use of any timestamp columns in the table being updated. Of these two approaches, specifying all the fields is the most realistic because using a timestamp requires that you copy the current timestamp value from the row into the updategram before executing it.

The following updategram specifies all the fields in the Shippers table in the before element:

 <?xml version="1.0"?> <UpdateShipper xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Shippers Shipper                 CompanyName="Speedy Express"                 Phone="(503) 555-9831"/>         </updg:before>         <updg:after>             <Shippers HomePhone="(503) 555-1122"/>         </updg:after>     </updg:sync> </UpdateShipper> 

In this case, an update of any of the columns by another user between the before and after elements causes this updategram to return an error message. The equivalent Transact-SQL statement for the after element is the following:

 UPDATE Shippers SET Phone='(503) 555-1122' WHERE ShipperID=1 AND CompanyName='Speedy Express' AND Phone='(503) 555-9831' 

Combining INSERT, UPDATE, and DELETE Operations in an Updategram

So far, we've used updategrams to insert, update, or delete data, each operation by itself, which is probably the most realistic scenario. However, a business process might occasionally involve a combination of two, or all three, of these actions. You can use a single updategram to perform a combination of INSERT, UPDATE, and DELETE operations by using the id attribute to identify each individual data-modification operation.

For example, you could use the following updategram to update a customer record and add an order for that customer to the database:

 <CustOrder xmlns:updg="urn:schemas-microsoft-com:xml-updategram">     <updg:sync>         <updg:before>             <Customers updg: Customer/>         </updg:before>         <updg:after>             <Customers updg: ContactName="Charles"/>             <Orders updg: updg:at-identity="NewID"                  Customer OrderDate="01/01/2001"/>             <Order_x0020_Details updg: Order                 Product                 UnitPrice="$1.00"                 Quantity="1" 
                 Discount="0.00"/>        </updg:after>     </updg:sync> </CustOrder> 

You can view this updategram in the UpdateAndInsert.xml file in the Demos\Chapter8\Updategrams folder on the companion CD. You can execute it by opening the Update And Insert shortcut in the Demos\Chapter8 folder. Notice that a different id attribute is used for each operation in the updategram. The UpdtCust string matches the before and after elements of the UPDATE operation (which changes the customer's ContactName field), and the InstOrd and InstOrdDet id attributes identify the INSERT operations (which insert a record into the Orders and OrderDetails tables, respectively).



Programming Microsoft SQL Server 2000 With Xml
Programming Microsoft SQL Server(TM) 2000 with XML (Pro-Developer)
ISBN: 0735613699
EAN: 2147483647
Year: 2005
Pages: 89

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net