Datensatzgenerierungsprozess (SQLXML 4.0)
Beim XML-Massenladen werden die XML-Eingabedaten verarbeitet und Datensätze für die entsprechenden Tabellen in Microsoft SQL Server vorbereitet. Die interne Logik beim XML-Massenladen entscheidet darüber, wann ein neuer Datensatz generiert wird, welche untergeordneten Elemente oder Attributwerte in die Datensatzfelder kopiert werden und wann der Datensatz vollständig ist und zum Einfügen an SQL Server gesendet werden kann.
Beim XML-Massenladen werden nicht alle XML-Eingabedaten in den Speicher geladen und keine vollständigen Datensätze erstellt, bevor Daten an SQL Server gesendet werden. Dies liegt daran, dass XML-Eingabedaten sehr große Dokumente bilden können und das Laden des gesamten Dokuments in den Speicher kostspielig sein kann. Stattdessen wird beim XML-Massenladen wie folgt vorgegangen:
Analysieren des Zuordnungsschemas und Vorbereiten des notwendigen Ausführungsplans.
Anwenden des Ausführungsplans auf die Daten im Eingabedatenstrom.
Aufgrund dieser sequenziellen Verarbeitung müssen die XML-Eingabedaten auf eine bestimmte Weise bereitgestellt werden. Mit den entsprechenden Kenntnissen darüber, wie beim XML-Massenladen das Zuordnungsschema analysiert wird und wie der Prozess der Datensatzgenerierung abläuft, können Sie ein Zuordnungsschema bereitstellen, mit dem die gewünschten Ergebnisse erzielt werden.
Beim XML-Massenladen werden gängige Anmerkungen im Zuordnungsschema verarbeitet, darunter Spalten- und Tabellenzuordnungen (die explizit über Anmerkungen oder implizit über die Standardzuordnung angegeben werden), sowie Verknüpfungsbeziehungen.
Hinweis |
---|
Es wird davon ausgegangen, dass Sie mit XSD- oder XDR-Zuordnungsschemas mit Anmerkungen vertraut sind. Weitere Informationen zu Schemas finden Sie unter Einführung in XSD-Schemas mit Anmerkungen (SQLXML 4.0) oder XDR-Schemas mit Anmerkungen (in SQLXML 4.0 veraltet). |
Grundlage für das Verständnis der Datensatzgenerierung sind folgende Konzepte:
Bereich eines Knotens
Datensatzgenerierungsregel
Datensatzteilmenge und Schlüsselsortierregel
Ausnahmen von der Datensatzgenerierungsregel
Bereich eines Knotens
Ein Knoten (ein Element oder Attribut) in einem XML-Dokument gelangt in den Bereich, sobald er beim XML-Massenladen im XML-Eingabedatenstrom gefunden wird. Bei Elementknoten bringt das Starttag des Elements das Element in den Bereich. Bei Attributknoten bringt der Attributname das Attribut in den Bereich.
Ein Knoten verlässt den Bereich, wenn keine Daten mehr dafür vorliegen, das heißt entweder am Endtag (im Fall eines Elementknotens) oder am Ende eines Attributwerts (im Fall eines Attributknotens).
Datensatzgenerierungsregel
Gelangt ein (Element- oder Attribut-) Knoten in den Bereich, kann daraus ein Datensatz generiert werden. Der Datensatz besteht weiter, solange der zugeordnete Knoten im Bereich ist. Verlässt der Knoten den Bereich, wird der generierte Datensatz als vollständig (mit Daten) betrachtet und zum Einfügen an SQL Server gesendet.
Betrachten Sie beispielsweise das folgende XSD-Schemafragment:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:element name="Customer" sql:relation="Customers" >
<xsd:complexType>
<xsd:attribute name="CustomerID" type="xsd:string" />
<xsd:attribute name="CompanyName" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
Das Schema gibt ein <Customer>-Element mit den Attributen CustomerID und CompanyName an. Die sql:relation-Anmerkung ordnet der <Customers>-Tabelle das <Customer>-Element zu.
Betrachten Sie dieses Fragment eines XML-Dokuments:
<Customer CustomerID="1" CompanyName="xyz" />
<Customer CustomerID="2" CompanyName="abc" />
...
Wenn für das XML-Massenladen das in den vorstehenden Absätzen erläuterte Schema und XML-Daten als Eingabe bereitgestellt werden, werden die (Element- und Attribut-) Knoten in den Quelldaten wie folgt verarbeitet:
Das Starttag des ersten <Customer>-Elements bringt dieses Element in den Bereich. Dieser Knoten ist der Customers-Tabelle zugeordnet. Beim XML-Massenladen wird daher ein Datensatz für die Customers-Tabelle generiert.
Im Schema sind alle Attribute des <Customer>-Elements bestimmten Spalten der Customers-Tabelle zugeordnet. Wenn diese Attribute in den Bereich gelangen, werden ihre Werte in den Kundendatensatz kopiert, der bereits vom übergeordneten Bereich generiert wurde.
Gelangt das XML-Massenladen zum Endtag für das <Customer>-Element, wird dieses Element aus dem Bereich ausgeschlossen. Damit wird der Datensatz als vollständig betrachtet und an SQL Server gesendet.
Bei jedem nachfolgenden <Customer>-Element wird beim XML-Massenladen nach diesem Prozess vorgegangen.
Wichtig |
---|
Da in diesem Modell ein Datensatz eingefügt wird, wenn das Endtag erreicht ist (oder der Knoten den Bereich verlässt), müssen Sie alle mit dem Datensatz verknüpften Daten innerhalb des Knotenbereichs definieren. |
Datensatzteilmenge und Schlüsselsortierregel
Wenn Sie ein Zuordnungsschema angeben, das <sql:relationship> verwendet, werden diejenigen Datensätze als Teilmenge bezeichnet, die auf der Fremdschlüsselseite der Beziehung generiert werden. Im folgenden Beispiel sind die CustOrder-Datensätze auf der Fremdschlüsselseite, <sql:relationship>.
Nehmen Sie z. B. an, dass eine Datenbank die folgenden Tabellen enthält:
Cust (CustomerID, CompanyName, City)
CustOrder (CustomerID, OrderID)
Die CustomerID in der CustOrder-Tabelle ist ein Fremdschlüssel, der auf den CustomerID-Primärschlüssel in der Cust-Tabelle verweist.
Betrachten Sie jetzt die im folgenden XSD-Schema mit Anmerkungen angegebene XML-Sicht. Dieses Schema verwendet <sql:relationship>, um die Beziehung zwischen den Tabellen Cust und CustOrder anzugeben.
<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="CustCustOrder"
parent="Cust"
parent-key="CustomerID"
child="CustOrder"
child-key="CustomerID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Customers" sql:relation="Cust" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerID" type="xsd:integer" />
<xsd:element name="CompanyName" type="xsd:string" />
<xsd:element name="City" type="xsd:string" />
<xsd:element name="Order"
sql:relation="CustOrder"
sql:relationship="CustCustOrder" >
<xsd:complexType>
<xsd:attribute name="OrderID" type="xsd:integer" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Die XML-Beispieldaten und die Schritte zum Erstellen eines funktionierenden Beispiels sind unten aufgeführt.
Wenn ein <Customer>-Elementknoten in der XML-Datendatei in den Bereich gelangt, wird beim XML-Massenladen ein Datensatz für die Cust-Tabelle generiert. Anschließend werden die erforderlichen Spaltenwerte (CustomerID, CompanyName und City) aus den untergeordneten Elementen <CustomerID>, <CompanyName> und <City> kopiert, sobald diese Elemente in den Bereich gelangen.
Wenn ein <Order>-Elementknoten in den Bereich gelangt, wird ein Datensatz für die CustOrder-Tabelle generiert. Beim XML-Massenladen wird der Wert des OrderID-Attributs in diesen Datensatz kopiert. Der erforderliche Wert für die CustomerID-Spalte wird aus dem untergeordneten <CustomerID>-Element des <Customer>-Elements abgerufen. Beim XML-Massenladen werden zum Abrufen des CustomerID-Fremdschlüsselwerts für diesen Datensatz die in <sql:relationship> angegebenen Informationen verwendet, es sei denn, im <Order> -Element wurde das CustomerID-Attribut angegeben. Generell gilt, dass beim XML-Massenladen der explizit im untergeordneten Element als Fremdschlüsselattribut angegebene Wert verwendet wird (sofern vorhanden) und er nicht über <sql:relationship> aus dem übergeordneten Element abgerufen wird. Verlässt dieser <Order>-Elementknoten den Bereich, werden beim XML-Massenladen der Datensatz an SQL Server gesendet und dann alle nachfolgenden <Order>-Elementknoten in derselben Weise verarbeitet.
Schließlich verlässt der <Customer>-Elementknoten den Bereich. Der Kundendatensatz wird daraufhin an SQL Server gesendet. Bei allen nachfolgenden Kunden im XML-Datenstrom wird nach demselben Prozess vorgegangen.
Zwei Beobachtungen zum Zuordnungsschema:
Erfüllt das Schema die "Einkapselungs"-Regel (Beispiel: Alle mit dem Kunden und dem Auftrag verknüpften Daten sind innerhalb des Bereichs des entsprechenden <Customer>-Elementknotens und <Order>-Elementknotens definiert), ist das Massenladen erfolgreich.
Bei der Beschreibung des <Customer>-Elements werden seine untergeordneten Elemente in der entsprechenden Reihenfolge angegeben. In diesem Fall wird das untergeordnete <CustomerID>-Element vor dem untergeordneten <Order>-Element angegeben. Das bedeutet, dass der <CustomerID>-Elementwert in der XML-Eingabedatendatei als Fremdschlüsselwert verfügbar ist, wenn das <Order>-Element in den Bereich gelangt. Die Schlüsselattribute werden gemäß der "Schlüsselsortierregel" zuerst angegeben.
Wenn Sie das untergeordnete <CustomerID>-Element nach dem untergeordneten <Order>-Element angeben, ist der Wert nicht verfügbar, wenn das <Order>-Element in den Bereich gelangt. Wird dann das </Order>-Endtag gelesen, wird der Datensatz für die CustOrder-Tabelle als vollständig angesehen und mit einem NULL-Wert für die CustomerID-Spalte in die CustOrder-Tabelle eingefügt. Dies entspricht nicht dem gewünschten Ergebnis.
So erstellen Sie ein funktionierendes Beispiel
Speichern Sie das in diesem Beispiel bereitgestellte Schema unter dem Dateinamen SampleSchema.xml.
Erstellen Sie die folgenden Tabellen:
CREATE TABLE Cust ( CustomerID int PRIMARY KEY, CompanyName varchar(20) NOT NULL, City varchar(20) DEFAULT 'Seattle') GO CREATE TABLE CustOrder ( OrderID int PRIMARY KEY, CustomerID int FOREIGN KEY REFERENCES Cust(CustomerID)) GO
Speichern Sie die folgenden XML-Eingabedaten unter dem Dateinamen SampleXMLData.xml:
<ROOT> <Customers> <CustomerID>1111</CustomerID> <CompanyName>Hanari Carnes</CompanyName> <City>NY</City> <Order OrderID="1" /> <Order OrderID="2" /> </Customers> <Customers> <CustomerID>1112</CustomerID> <CompanyName>Toms Spezialitten</CompanyName> <City>LA</City> <Order OrderID="3" /> </Customers> <Customers> <CustomerID>1113</CustomerID> <CompanyName>Victuailles en stock</CompanyName> <Order OrderID="4" /> </Customers> </ROOT>
Speichern Sie folgendes Microsoft Visual Basic Scripting Edition (VBScript)-Beispiel unter dem Dateinamen BulkLoad.vbs, und führen Sie es aus, um das XML-Massenladen auszuführen:
set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkload.4.0") objBL.ConnectionString = "provider=SQLOLEDB;data source=localhost;database=tempdb;integrated security=SSPI" objBL.ErrorLogFile = "c:\error.log" objBL.CheckConstraints = True objBL.Execute "c:\SampleSchema.xml", "c:\SampleXMLData.xml" set objBL=Nothing
Ausnahmen von der Datensatzgenerierungsregel
Gelangt ein Knoten vom Typ IDREF oder IDREFS in den Bereich, wird kein Datensatz generiert. Stellen Sie sicher, dass an irgendeiner Stelle im Schema eine vollständige Beschreibung des Datensatzes vorhanden ist. Die dt:type="nmtokens"-Anmerkungen werden ebenso wie der IDREFS-Typ ignoriert.
Das folgende XSD-Schema beschreibt beispielsweise die Elemente <Customer> und <Order>. Das <Customer>-Element schließt ein OrderList-Attribut des IDREFS-Typs ein. Das <sql:relationship>-Tag gibt die 1:n-Beziehung zwischen dem Kunden und der Auftragsliste an.
Das ist das Schema:
<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="CustCustOrder"
parent="Cust"
parent-key="CustomerID"
child="CustOrder"
child-key="CustomerID" />
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Customers" sql:relation="Cust" >
<xsd:complexType>
<xsd:attribute name="CustomerID" type="xsd:integer" />
<xsd:attribute name="CompanyName" type="xsd:string" />
<xsd:attribute name="City" type="xsd:string" />
<xsd:attribute name="OrderList"
type="xsd:IDREFS"
sql:relation="CustOrder"
sql:field="OrderID"
sql:relationship="CustCustOrder" >
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="Order" sql:relation="CustOrder" >
<xsd:complexType>
<xsd:attribute name="OrderID" type="xsd:string" />
<xsd:attribute name="CustomerID" type="xsd:integer" />
<xsd:attribute name="OrderDate" type="xsd:date" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
Da die Knoten vom IDREFS-Typ ignoriert werden, wird kein Datensatz generiert, wenn der OrderList-Attributknoten in den Bereich gelangt. Um die Auftragsdatensätze der Orders-Tabelle hinzuzufügen, müssen Sie demnach diese Aufträge irgendwo im Schema beschreiben. In diesem Schema stellen Sie durch die Angabe des <Order>-Elements sicher, dass beim XML-Massenladen die Auftragsdatensätze der Orders-Tabelle hinzugefügt werden. Das <Order>-Element beschreibt alle zum Auffüllen des Datensatzes für die <CustOrder>-Tabelle erforderlichen Attribute.
Stellen Sie sicher, dass die Werte für CustomerID und OrderID im <Customer>-Element den Werten im <Order>-Element entsprechen. Sie sind verantwortlich für die Wahrung der referenziellen Integrität.
So testen Sie ein funktionierendes Beispiel
Erstellen Sie die folgenden Tabellen:
CREATE TABLE Cust ( CustomerID int PRIMARY KEY, CompanyName varchar(20) NOT NULL, City varchar(20) DEFAULT 'Seattle') GO CREATE TABLE CustOrder ( OrderID varchar(10) PRIMARY KEY, CustomerID int FOREIGN KEY REFERENCES Cust(CustomerID), OrderDate datetime DEFAULT '2000-01-01') GO
Speichern Sie das in diesem Beispiel bereitgestellte Zuordnungsschema unter dem Dateinamen SampleSchema.xml.
Speichern Sie die folgenden XML-Daten unter dem Dateinamen SampleXMLData.xml:
<ROOT> <Customers CustomerID="1111" CompanyName="Sean Chai" City="NY" OrderList="Ord1 Ord2" /> <Customers CustomerID="1112" CompanyName="Dont Know" City="LA" OrderList="Ord3 Ord4" /> <Order OrderID="Ord1" CustomerID="1111" OrderDate="1999-01-01" /> <Order OrderID="Ord2" CustomerID="1111" OrderDate="1999-02-01" /> <Order OrderID="Ord3" CustomerID="1112" OrderDate="1999-03-01" /> <Order OrderID="Ord4" CustomerID="1112" OrderDate="1999-04-01" /> </ROOT>
Speichern Sie dieses VBScript-Beispiel (SampleVB.vbs), und führen Sie es aus, um das XML-Massenladen auszuführen:
set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkload.4.0") objBL.ConnectionString = "provider=SQLOLEDB;data source=localhost;database=tempdb;integrated security=SSPI" objBL.ErrorLogFile = "c:\error.log" objBL.CheckConstraints=True objBL.Execute "c:\SampleSchema.xml", "c:\SampleXMLData.xml" set objBL=Nothing