XML アップデートグラムを使用した、データの更新 (SQLXML 4.0)
既存のデータを更新するときには、<before> と <after> の両方のブロックを指定する必要があります。 <before> および <after> ブロックで要素を指定し、必要な変更を記述します。 アップデートグラムでは、<before> ブロックに指定された要素から、データベースの既存のレコードが特定されます。 <after> ブロックの対応する要素では、更新操作の実行後のレコードの状態を記述します。 アップデートグラムでは、この情報を基に <after> ブロックに一致する SQL ステートメントが作成された後、 そのステートメントによってデータベースが更新されます。
更新操作のアップデートグラムの形式は次のとおりです。
<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 属性では、アップデートグラムで使用するマッピング スキーマを指定します。 アップデートグラムにマッピング スキーマを指定する場合、<before> および <after> ブロックで指定する要素と属性の名前は、スキーマ内の名前と一致する必要があります。 マッピング スキーマでは、これらの要素または属性の名前がデータベース テーブルと列の名前にマップされます。
アップデートグラムにスキーマを指定しない場合は、アップデートグラムで既定のマッピングが使用されます。 既定のマッピングでは、アップデートグラムに指定した <ElementName> がデータベース テーブルにマップされ、子要素または属性がデータベース列にマップされます。
<before> ブロックの要素は、データベース内の 1 つのテーブル行だけに一致する必要があります。 要素が複数のテーブル行に一致する場合、またはどのテーブル行にも一致しない場合、アップデートグラムではエラーが返され、<sync> ブロック全体の操作が取り消されます。
アップデートグラムには、複数の <sync> ブロックを含めることができます。 それぞれの <sync> ブロックは 1 つのトランザクションとして扱われ、 複数の <before> および <after> ブロックを含めることができます。 たとえば、既存のレコードを 2 つ更新する場合は、更新するレコードごとに <before> と <after> を 1 組ずつ、合計 2 組指定できます。
updg:id 属性の使用
<before> および <after> ブロックに複数の要素を指定する場合は、updg:id 属性を使用して、<before> および <after> ブロック内の行をマークします。 処理ロジックではこの情報を基に、<before> ブロック内のレコードと <after> ブロック内のレコードの組が決定されます。
次のいずれかに該当する場合、updg:id 属性は必ずしも必要ではありません (ただし使用が推奨されます)。
指定したマッピング スキーマの要素に sql:key-fields 属性がある。
アップデートグラムのキー フィールドに特定の値が 1 つ以上提供されている。
このどちらかに該当する場合、アップデートグラムでは sql:key-fields で指定されたキー列を基に、<before> ブロックと <after> ブロック内の要素の組が決定されます。
マッピング スキーマで sql:key-fields によりキー列が指定されていない場合、またはアップデートグラムでキー列の値を更新する場合は、updg:id を指定する必要があります。
<before> および <after> ブロックで指定されるレコードは、同じ順序である必要はありません。 updg:id 属性では、<before> および <after> ブロックで指定された要素の間の関係が強制的に設定されます。
<before> ブロックに 1 つの要素を指定し、<after> ブロックに対応する要素を 1 つだけ指定する場合、updg:id を使用する必要はありません。 ただし、あいまいになるのを避けるため、この場合も updg:id を指定することをお勧めします。
使用例
アップデートグラムの例を使用する前に、次のことに注意してください。
ほとんどの例では、アップデートグラムでマッピング スキーマを指定せず、既定のマッピングを使用します。 マッピング スキーマを使用するアップデートグラムの例については、「アップデートグラムでの注釈付きマッピング スキーマの指定 (SQLXML 4.0)」を参照してください。
ほとんどの例では、AdventureWorks サンプル データベースを使用します。 すべての更新内容は、このデータベースのテーブルに適用されます。 AdventureWorks データベースは復元できます。
A. レコードを更新する
次のアップデートグラムでは、AdventureWorks データベースの Person.Contact テーブルで、従業員の姓を Fuller に更新します。 アップデートグラムにマッピング スキーマは指定しないので、既定のマッピングが使用されます。
<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> ブロックで記述するレコードは、データベースの現在のレコードです。 アップデートグラムでは <before> ブロックで指定されたすべての列値を基にレコードが検索されます。 このアップデートグラムの <before> ブロックでは ContactID 列だけを指定します。したがってアップデートグラムではこの値だけを基にレコードが検索されます。 仮に、このブロックに LastName 値を追加した場合は、検索に ContactID と LastName の両方の値が使用されます。
ここでは LastName 列の値だけを変更するので、このアップデートグラムの <after> ブロックでは LastName 列の値だけを指定します。
アップデートグラムをテストするには
上のアップデートグラムのテンプレートをコピーして、テキスト ファイルに貼り付け、 UpdateLastName.xml として保存します。
SQLXML 4.0 テスト スクリプト (Sqlxml4test.vbs) を作成し、それを使用してアップデートグラムを実行します。
詳細については、「ADO を使用した、SQLXML 4.0 クエリの実行」を参照してください。
B. updg:id 属性を使用して複数のレコードを更新する
この例では、アップデートグラムで、AdventureWorks データベースの HumanResources.Shift テーブルに次の 2 つの更新操作を行います。
7:00AM から始まる勤務時間の名前を "Day" から "Early Morning" に変更する。
10:00AM から始まる、"Late Morning" という名前の新しい勤務時間を挿入する。
アップデートグラムでは、updg:id 属性によって、<before> ブロックと <after> ブロックの要素が関係付けられます。
<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> 要素と <after> ブロックの 2 番目の <HumanResources.Shift> 要素が組み合わせられることに注意してください。
アップデートグラムをテストするには
上のアップデートグラムのテンプレートをコピーして、テキスト ファイルに貼り付け、 UpdateMultipleRecords.xml として保存します。
SQLXML 4.0 テスト スクリプト (Sqlxml4test.vbs) を作成し、それを使用してアップデートグラムを実行します。
詳細については、「ADO を使用した、SQLXML 4.0 クエリの実行」を参照してください。
C. 複数の <before> および <after> ブロックを指定する
例 B のアップデートグラムは、複数の <before> および <after> ブロックの組を使ってより明確に書き換えることができます。 <before> と <after> の組を指定することは、複数の更新操作をわかりやすく行うための 1 つの方法です。 また、<before> ブロックと <after> ブロックのそれぞれに 1 つの要素だけを指定すれば、updg:id 属性を使用する必要はありません。
注 |
---|
組を作るには、<before> タグの直後に、対応する <after> タグを記述する必要があります。 |
次のアップデートグラムでは、最初の <before> および <after> の組によって勤務時間の名前が更新され、 2 番目の組によって新しい勤務時間のレコードが挿入されます。
<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>
アップデートグラムをテストするには
上のアップデートグラムのテンプレートをコピーして、テキスト ファイルに貼り付け、 UpdateMultipleBeforeAfter.xml として保存します。
SQLXML 4.0 テスト スクリプト (Sqlxml4test.vbs) を作成し、それを使用してアップデートグラムを実行します。
詳細については、「ADO を使用した、SQLXML 4.0 クエリの実行」を参照してください。
D. 複数の <sync> ブロックを指定する
1 つのアップデートグラムに、複数の <sync> ブロックを指定できます。 指定したそれぞれの <sync> ブロックは、独立したトランザクションとして扱われます。
次のアップデートグラムでは、最初の <sync> ブロックによって Sales.Customer テーブル内のレコードが更新されます。 簡素化するため、アップデートグラムでは ID 値 (CustomerID) と更新する値 (SalesPersonID) の 2 つの必要な値だけを指定します。
2 番目の <sync> ブロックでは、Sales.SalesOrderHeader テーブルに 2 つのレコードを追加します。 このテーブルで、SalesOrderID は IDENTITY 型の列です。 したがって、アップデートグラムでは各 <Sales.SalesOrderHeader> 要素に SalesOrderID の値は指定しません。
複数の <sync> ブロックを指定すると、2 番目の <sync> ブロック (トランザクション) による Sales.SalesOrderHeader テーブルへのレコード追加が失敗した場合も、最初の <sync> ブロックによる 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>
アップデートグラムをテストするには
上のアップデートグラムのテンプレートをコピーして、テキスト ファイルに貼り付け、 UpdateMultipleSyncs.xml として保存します。
SQLXML 4.0 テスト スクリプト (Sqlxml4test.vbs) を作成し、それを使用してアップデートグラムを実行します。
詳細については、「ADO を使用した、SQLXML 4.0 クエリの実行」を参照してください。
E. マッピング スキーマを使用する
この例では、アップデートグラムで mapping-schema を使用してマッピング スキーマを指定します。 ここでは既定のマッピングはなく、アップデートグラム内の要素および属性と、データベースのテーブルおよび列の間の必要なマッピングはマッピング スキーマによって指定します。
アップデートグラムで指定する要素と属性は、マッピング スキーマ内の要素と属性を参照します。
次の XSD マッピング スキーマには、<Customer>、<Order>、および <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) を次のアップデートグラムで指定します。 このアップデートグラムでは、Sales.SalesOrderDetail テーブルの特定の注文アイテムに、注文明細アイテムを追加します。 このアップデートグラムでは、<Order> 要素内に <OD> 要素が入れ子になっています。 これら 2 つの要素の主キーと外部キーのリレーションシップは、マッピング スキーマで指定されます。
<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>
アップデートグラムをテストするには
上のマッピング スキーマをコピーして、テキスト ファイルに貼り付け、 UpdategramMappingSchema.xml として保存します。
上のアップデートグラムのテンプレートをコピーして、テキスト ファイルに貼り付け、 マッピング スキーマ (UpdategramMappingSchema.xml) と同じフォルダーに UpdateWithMappingSchema.xml として保存します。
SQLXML 4.0 テスト スクリプト (Sqlxml4test.vbs) を作成し、それを使用してアップデートグラムを実行します。
詳細については、「ADO を使用した、SQLXML 4.0 クエリの実行」を参照してください。
マッピング スキーマを使用するアップデートグラムの例については、「アップデートグラムでの注釈付きマッピング スキーマの指定 (SQLXML 4.0)」を参照してください。
F. マッピング スキーマを IDREFS 属性と共に使用する
この例では、アップデートグラムでマッピング スキーマ内の IDREFS 属性を使用して、複数のテーブルのレコードを更新する方法を示します。 この例では、データベースは次のテーブルから構成されるものとします。
Student (StudentID、LastName)
Course (CourseID、CourseName)
Enrollment (StudentID、CourseID)
学生 (Student) は複数の講座 (Course) に登録できるので、Course には複数の Student を含めることができます。3 番目のテーブル Enrollment は、この M:N リレーションシップを表すために必要です。
次の XSD マッピング スキーマでは、<Student>、<Course>、および <Enrollment> 要素を使用してテーブルの XML ビューを提供します。 マッピング スキーマ内の IDREFS 属性では、これらの要素の間のリレーションシップを指定します。 <Course> 要素の StudentIDList 属性は IDREFS 型の属性で、Enrollment テーブルの StudentID 列を指します。 同様に、<Student> 要素の EnrolledIn 属性は IDREFS 型の属性で、Enrollment テーブルの CourseID 列を指します。
<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>
アップデートグラムでこのスキーマを指定して Course テーブルにレコードを挿入すると、Course テーブルには常に新しい講座レコードが挿入されます。 StudentIDList 属性に 1 つ以上の新しい学生 ID を指定すると、アップデートグラムでは Enrollment テーブルにも新しい学生ごとのレコードが挿入され、 重複した値が追加されていないことが Enrollment テーブルで確認されます。
アップデートグラムをテストするには
仮想ルートに指定したデータベースに、これらのテーブルを作成します。
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))
次のサンプル データを追加します。
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')
上のマッピング スキーマをコピーして、テキスト ファイルに貼り付け、 SampleSchema.xml として保存します。
上の手順のマッピング スキーマと同じフォルダーに、アップデートグラム (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>
SQLXML 4.0 テスト スクリプト (Sqlxml4test.vbs) を作成し、それを使用してアップデートグラムを実行します。
詳細については、「ADO を使用した、SQLXML 4.0 クエリの実行」を参照してください。
上の手順の説明どおり、次のアップデートグラムを保存して実行します。 このアップデートグラムでは、Enrollment テーブルにレコードを追加し、講義 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" /> </updg:before> <updg:after > <Student updg:id="x" StudentID="S1" LastName="Davolio" EnrolledIn="CS101 CS102" /> </updg:after> </updg:sync> </ROOT>
前の手順の説明どおり、次のアップデートグラムを保存して実行します。 このアップデートグラムでは、新しい学生を 3 人追加し、講座 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>
マッピング スキーマを使用するアップデートグラムの例については、「アップデートグラムでの注釈付きマッピング スキーマの指定 (SQLXML 4.0)」を参照してください。