Процесс формирования записей (SQLXML 4.0)
Массовая загрузка XML обрабатывает входные XML-данные и готовит записи для соответствующих таблиц в Microsoft SQL Server. Логика массовой загрузки XML определяет, когда формируется новая запись, какие значения дочерних элементов или атрибута копировать в поля записи, и когда запись завершена и готова к отправке в SQL Server для вставки.
Массовая загрузка XML не загружает все входные XML-данные и не формирует полных наборов записей перед отправкой данных в SQL Server. Это объясняется тем, что входные XML-данные могут быть большим документом, и загрузка целого документа в память может быть дорогостоящей. Вместо этого массовая загрузка XML выполняет следующие действия:
Анализирует схему сопоставления и готовить необходимый план выполнения.
Применяет план выполнения к данным во входном потоке.
В связи с такой последовательной обработкой важно представить входные XML-данные определенным образом. Необходимо понимать, как массовая загрузка XML анализирует схему сопоставления, и процесс создания записи. Благодаря такому пониманию можно предоставить схему сопоставления для массовой загрузки XML, которая принесет нужные результаты.
Массовая загрузка XML обрабатывает распространенные заметки схемы сопоставления, в том числе сопоставления столбцов и таблиц (указанных явно с использованием заметок или неявно через сопоставление по умолчанию) и соединительные связи.
Примечание |
---|
Предполагается, что пользователь знаком с аннотированными схемами сопоставления XSD и XDR. Дополнительные сведения о схемах см. в разделах Введение в схемы XSD с заметками (SQLXML 4.0) и Схемы XDR с заметками (устарели в SQLXML 4.0). |
Чтобы понять формирование записей, необходимо понимать следующие концепции:
Набор узла
Правило формирования записей
Подмножество записей и правило упорядочения ключа
Исключения из правила формирования записей
Набор узла
Узел (элемент или атрибут) в XML-документе вводится в набор, когда массовая загрузка XML встречает его во входном потоке XML-данных. Для узла элемента открывающий тег элемента вводит элемент в набор. Для узла атрибута имя атрибута вводит атрибут в набор.
Узел выводится из набора, когда в нем более не остается данных: по закрывающему тегу (в случае узла элемента) или по окончанию значения атрибута (в случае узла атрибута).
Правило формирования записей
Когда узел (элемент или атрибут) вводится в набор, существует возможность формирования записи из этого узла. Запись существует так же долго, как связанный узел в наборе. Когда узел выводится из набора, массовая загрузка XML рассматривает сформированную запись как полную (с данными) и отправляет их в SQL Server для вставки.
Например, рассмотрим следующий фрагмент схемы XSD:
<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>
Схема указывает элемент <Customer> с атрибутами CustomerID и CompanyName. Заметка sql:relation сопоставляет элемент <Customer> с таблицей Customers.
Рассмотрим следующий фрагмент XML-документа:
<Customer CustomerID="1" CompanyName="xyz" /><Customer CustomerID="2" CompanyName="abc" />...
Когда массовой загрузке XML предоставляется схема, описанная в предыдущих абзацах, и XML-данные в качестве ввода, она обрабатывает узлы (элементы и атрибуты) в источнике данных следующим образом:
Открывающий тег первого элемента <Customer> вводит этот элемент в набор. Этот сопоставляется таблице Customers. Поэтому массовая загрузка XML формирует запись для таблицы Customers.
Все атрибуты элемента <Customer> в схеме сопоставляются столбцам таблицы Customers. По мере ввода этих атрибутов в набор, массовая загрузка XML копирует их значения в запись потребителя, уже сформированную родительским набором.
Когда массовая загрузка XML достигает закрывающего тега для элемента <Customer>, элемент выводится из набора. В результате массовая загрузка XML воспринимает запись как завершенную и отправляет ее в SQL Server.
Массовая загрузка XML выполняет этот процесс для каждого последующего элемента <Customer>.
Важно! |
---|
В этой модели, поскольку запись вставляется при достижении закрывающего тега (или узел вне набора), необходимо определить все данные, связанные с записью в наборе узла. |
Подмножество записей и правило упорядочения ключа
При задании схемы сопоставления, в которой используется <sql:relationship>, термин «подмножество» относится к набору записей, сформированных на стороне внешнего ключа связи. В следующем примере записи CustOrder находятся на стороне внешнего ключа, <sql:relationship>.
Например, пусть база данных содержит следующие таблицы.
Cust (CustomerID, CompanyName, City)
CustOrder (CustomerID, OrderID)
CustomerID в таблице CustOrder является внешним ключом, под которым понимается первичный ключ CustomerID в таблице Cust.
А теперь обратите внимание на представление XML, заданное в следующей аннотированной схеме XSD. В этой схеме используется <sql:relationship>, чтобы указать связь между таблицами Cust и CustOrder.
<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>
Ниже приведены образец XML-данных и шаги для создания рабочего образца.
Когда узел элемента <Customer> в файле XML-данных вводится в набор, массовая загрузка XML формирует запись для таблицы Cust. Затем массовая загрузка XML копирует необходимые значения столбцов (CustomerID, CompanyName и City) из дочерних элементов <CustomerID>, <CompanyName> и <City>, когда эти элементы вводятся в набор.
Когда узел элемента <Order> вводится в набор, массовая загрузка XML формирует запись для таблицы CustOrder. Массовая загрузка XML копирует значения атрибута OrderID в эту запись. Значение, необходимое для столбца CustomerID, получается из дочернего элемента <CustomerID> элемента <Customer>. Массовая загрузка XML использует сведения, приведенные в <sql:relationship>, чтобы получить значение внешнего ключа CustomerID для этой записи, если только атрибут CustomerID не был указан в элементе <Order> . Общее правило: если дочерний элемент явно указывает значение для атрибута внешнего ключа, то массовая загрузка XML использует это значение и не получает значение из родительского элемента с использованием указанного <sql:relationship>. При выводе этого узла элемента <Order> из набора, массовая загрузка XML отправляет запись в SQL Server, а затем таким же обрабатывает все последующие узлы элементов <Order>.
Наконец, узел элемента <Customer> выводится из набора. В это время массовая загрузка XML отправляет запись потребителя в SQL Server. Массовая загрузка XML выполняет этот процесс для всех последующих потребителей в потоке данных XML.
Два замечания о схеме сопоставления:
Если схема удовлетворяет правилу включения (например, все данные, связанные с потребителем и заказом, определяются в наборе связанных узлов элементов <Customer> и <Order>), массовая загрузка завершается успехом.
При описании элемента <Customer> его дочерние элементы указываются в соответствующем порядке. В этом случае дочерний элемент <CustomerID> указывается прежде дочернего элемента <Order>. Это значит, что во входном файле XML-данных значение элемента <CustomerID> доступно в качестве значения внешнего ключа, когда элемент <Order> вводится в набор. Сначала указываются ключевые атрибуты; это «правило упорядочения ключа».
Если дочерний элемент <CustomerID> задан после дочернего элемента <Order>, значение недоступно, когда элемент <Order> вводится в набор. Когда затем считывается закрывающий тег </Order>, запись для таблицы CustOrder считается завершенной и вставляется в таблицу CustOrder со значением NULL для столбца CustomerID, что нежелательно.
Создание рабочего образца
Сохраните схему, приведенную в этом примере, в файле SampleSchema.xml.
Создайте следующие таблицы.
CREATE TABLE Cust ( CustomerID int PRIMARY KEY, CompanyName varchar(20) NOT NULL, City varchar(20) DEFAULT 'Seattle')GOCREATE TABLE CustOrder ( OrderID int PRIMARY KEY, CustomerID int FOREIGN KEY REFERENCES Cust(CustomerID))GO
Сохраните следующий образец входных XML-данных в файле 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>
Чтобы выполнить массовую загрузку XML-данных, сохраните следующий пример на языке Microsoft Visual Basic Scripting Edition (VBScript) в файле BulkLoad.vbs и выполните его.
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 = TrueobjBL.Execute "c:\SampleSchema.xml", "c:\SampleXMLData.xml"set objBL=Nothing
Исключения из правила формирования записей
Массовая загрузка XML не формирует запись для узла, когда он вводится в набор, если этот узел принадлежит типу IDREF или IDREFS. Необходимо убедиться, что в каком-то месте схемы дано полное описание записи. Заметки dt:type="nmtokens" пропускаются также, как пропускается тип IDREFS.
Например, рассмотрим следующий фрагмент схемы XSD, который описывает элементы <Customer> и <Order>. Элемент <Customer> включает атрибут OrderList типа IDREFS. Тег <sql:relationship> задает связь «один ко многим» между заказчиком и списком заказов.
Схема:
<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>
Поскольку массовая загрузка пропускает узлы типа IDREFS, записи не формируются, когда атрибут OrderList вводится в набор. Поэтому, если нужно упорядочить записи, добавленные в таблицу Orders, необходимо описать эти заказы в каком-то месте схемы. Указание элемента <Order> в этой схеме гарантирует, что массовая загрузка XML добавляет записи заказов в таблицу Orders. Элемент <Order> описывает все атрибуты, необходимые, чтобы заполнить запись для таблицы CustOrder.
Необходимо обеспечить соответствие значений CustomerID и OrderID в элементе <Customer> и значений в элементе <Order>. Пользователь ответственен за обеспечение ссылочной целостности.
Проверка рабочего образца
Создайте следующие таблицы.
CREATE TABLE Cust ( CustomerID int PRIMARY KEY, CompanyName varchar(20) NOT NULL, City varchar(20) DEFAULT 'Seattle')GOCREATE TABLE CustOrder ( OrderID varchar(10) PRIMARY KEY, CustomerID int FOREIGN KEY REFERENCES Cust(CustomerID), OrderDate datetime DEFAULT '2000-01-01')GO
Сохраните схему сопоставления, приведенную в этом примере, в файле SampleSchema.xml.
Сохраните следующий образец XML-данных в файле 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>
Чтобы выполнить массовую загрузку XML-данных, сохраните этот пример на языке VBScript в файле Sample.vbs и выполните его.
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=TrueobjBL.Execute "c:\SampleSchema.xml", "c:\SampleXMLData.xml"set objBL=Nothing