Правила и ограничения массовой загрузки XML (SQLXML 4.0)
Использование массовой загрузки XML требует понимания следующих рекомендаций и ограничений.
Встроенные схемы не поддерживаются.
Если в исходном XML-документе содержится встроенная схема, при массовой загрузке XML она не учитывается. Для массовой загрузки XML нужно задать схему сопоставления, внешнюю по отношению к XML-данным. Нельзя задать схему сопоставления в узле с помощью атрибута xmlns="x:schema".
Проверяется правильность формата XML-документа, но сам документ не проверяется.
При массовой загрузке производится проверка XML-документа, чтобы определить правильность формата, то есть убедиться, что конструкции XML соответствуют требованиям рекомендации консорциума W3C по языку XML 1.0. Если формат документа содержит ошибки, массовая загрузка XML прекращается и возвращает ошибку. Единственное исключение — когда документ является фрагментом (например, когда у него не один корневой элемент), в этом случае массовая загрузка XML загружает документ.
Массовая загрузка XML не проверяет документ на соответствие какой-либо схеме DTD или XML-Data, которую содержит или на которую ссылается файл XML-данных. Кроме того, массовая загрузка XML-данных не проверяет файл XML-данных на соответствие переданной схеме сопоставления.
Никакая информация из пролога XML-документа не учитывается.
Массовая загрузка XML пропускает любую информацию, помещенную до или после элемента <root> XML-документа. В частности, массовая загрузка XML не учитывает никаких XML-деклараций, внутренних определений DTD, ссылок на внешние DTD, комментариев и тому подобное.
При наличии схемы сопоставления, задающей связь «первичный ключ — внешний ключ» между двумя таблицами (например, между таблицами Customer и CustOrder), таблица, содержащая первичный ключ, должна описываться в схеме первой. Таблица со столбцом внешнего ключа должна располагаться после нее. Это объясняется тем, что порядок описания таблиц в схеме задает порядок, в котором таблицы загружаются в базу данных.Например, следующая схема XDR вызовет ошибку, если ее использовать в массовой загрузке XML, потому что элемент <Order> описан раньше элемента <Customer>. Столбец CustomerID в таблице CustOrder представляет собой столбец внешнего ключа, ссылающийся на столбец первичного ключа CustomerID в таблице Cust.
<?xml version="1.0" ?> <Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:xml:datatypes" xmlns:sql="urn:schemas-microsoft-com:xml-sql" > <ElementType name="Order" sql:relation="CustOrder" > <AttributeType name="OrderID" /> <AttributeType name="CustomerID" /> <attribute type="OrderID" /> <attribute type="CustomerID" /> </ElementType> <ElementType name="CustomerID" dt:type="int" /> <ElementType name="CompanyName" dt:type="string" /> <ElementType name="City" dt:type="string" /> <ElementType name="root" sql:is-constant="1"> <element type="Customers" /> </ElementType> <ElementType name="Customers" sql:relation="Cust" sql:overflow-field="OverflowColumn" > <element type="CustomerID" sql:field="CustomerID" /> <element type="CompanyName" sql:field="CompanyName" /> <element type="City" sql:field="City" /> <element type="Order" > <sql:relationship key-relation="Cust" key="CustomerID" foreign-key="CustomerID" foreign-relation="CustOrder" /> </element> </ElementType> </Schema>
Если в схеме не задан явным образом столбец переполнения с помощью заметки sql:overflow-field, массовая загрузка XML пропускает любые данные, которые присутствуют в XML-документе, но не описаны в схеме сопоставления.
Массовая загрузка XML применяет заданную схему сопоставления каждый раз, как в потоке XML-данных попадаются известные теги. Данные, которые присутствуют в XML-документе, но не описаны в схеме, пропускаются. Например, в схеме сопоставления описан элемент <Customer>. Файл XML-данных содержит корневой тег <AllCustomers> (не описанный в схеме), который заключает в себе все элементы <Customer>:
<AllCustomers> <Customer>...</Customer> <Customer>...</Customer> ... </AllCustomers>
В этом случае массовая загрузка XML не учитывает элемент <AllCustomers> и начинает сопоставление с элемента <Customer>. Массовая загрузка XML пропускает все элементы, не описанные в схеме, но присутствующие в XML-документе.
Рассмотрим другой исходный файл XML-данных, содержащий элементы <Order>. Эти элементы не описаны в схеме сопоставления.
<AllCustomers> <Customer>...</Customer> <Order> ... </Order> <Order> ... </Order> ... <Customer>...</Customer> <Order> ... </Order> <Order> ... </Order> ... ... </AllCustomers>
Массовая загрузка XML пропускает эти элементы <Order>. Но если в схеме с помощью заметки sql:overflow-field назначен столбец переполнения, массовая загрузка XML сохранит все неиспользованные данные в этом столбце.
Разделы CDATA и ссылки на сущности для сохранения их в базе данных преобразуются в эквивалентные строки.
В данном примере раздел CDATA содержит значение элемента <City>. Массовая загрузка XML извлекает строковое значение («NY») до помещения элемента <City> в базу данных.
<City><![CDATA[NY]]> </City>
Массовая загрузка XML не сохраняет ссылки на сущности.
Если в схеме сопоставления задано значение по умолчанию для атрибута и в исходных XML-данных этот атрибут отсутствует, при массовой загрузке XML будет использовано значение по умолчанию.
В следующем образце схемы XDR атрибуту HireDate назначается значение по умолчанию:
<?xml version="1.0" ?> <Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:xml:datatypes" xmlns:sql="urn:schemas-microsoft-com:xml-sql" > <ElementType name="root" sql:is-constant="1"> <element type="Customers" /> </ElementType> <ElementType name="Customers" sql:relation="Cust3" > <AttributeType name="CustomerID" dt:type="int" /> <AttributeType name="HireDate" default="2004-01-01" /> <AttributeType name="Salary" /> <attribute type="CustomerID" sql:field="CustomerID" /> <attribute type="HireDate" sql:field="HireDate" /> <attribute type="Salary" sql:field="Salary" /> </ElementType> </Schema>
В этих XML-данных отсутствует атрибут HireDate во втором элементе <Customers>. Когда при массовой загрузке XML второй элемент <Customers> помещается в базу данных, для него используется значение по умолчанию, заданное в схеме.
<ROOT> <Customers CustomerID="1" HireDate="2003-01-01" Salary="10000" /> <Customers CustomerID="2" Salary="10000" /> </ROOT>
Заметка sql:url-encode не поддерживается.
Нельзя задать во вводных XML-данных URL-адрес и ждать, что массовая загрузка XML прочтет данные, находящиеся по этому адресу.
Создаются таблицы, заданные в схеме сопоставления (база данных должна существовать). Если одна или несколько из этих таблиц уже имеются в базе данных, свойство SGDropTables указывает, следует ли удалить эти таблицы и создать их повторно.
Если задать свойство SchemaGen (например, SchemaGen = true), то будут созданы таблицы, заданные в схеме сопоставления. Но свойство SchemaGen не создает в этих таблицах никаких ограничений (например, типа «первичный-внешний ключ»), с единственным исключением: если для узлов XML, имеющих XML-тип ID (то есть type="xsd:ID" для XSD), и если свойство SGUseID для SchemaGen имеет значение True, то из узлов типа ID создаются не только первичные ключи, но и отношения «первичный-внешний ключ» на основе связей, заданных в схеме сопоставления.
Свойство SchemaGen не использует аспекты и расширения из схемы XSD для создания реляционной схемы SQL Server.
Если для массовой загрузки XML задать свойство SchemaGen (например, SchemaGen = true), обновляются только указанные таблицы (но не одноименные представления).
Свойство SchemaGen предоставляет только базовую функциональность для создания реляционной схемы из аннотированного XSD. При необходимости пользователь должен изменить созданные таблицы вручную.
Если между таблицами существует несколько связей, свойство SchemaGen пытается создать одну связь, включающую все ключи, по которым задается связь между этими таблицами. Это ограничение может вызвать ошибку Transact-SQL.
При массовой загрузке XML-данных в базу по меньшей мере один атрибут или дочерний элемент в схеме сопоставления должен быть сопоставлен со столбцом базы данных.
Если при массовой загрузке XML происходит вставка значений дат, эти значения должны быть заданы в формате (-)CCYY-MM-DD((+-)TZ). Это стандартный формат даты в XSD.
Некоторые флаги свойств несовместимы друг с другом. Например, при массовой загрузке не поддерживается значение Ignoreduplicatekeys=true вместе со значением Keepidentity=false. При использовании значения Keepidentity=false в операции массовой загрузки происходит ожидание создания сервером значений ключа. Таблицы должны иметь ограничение IDENTITY, которое распространяется на этот ключ. Сервер не будет создавать повторяющиеся ключи, а это означает, что нет необходимости присваивать атрибуту Ignoreduplicatekeys значение true. Атрибут Ignoreduplicatekeys должен иметь значение true только при передаче значений первичного ключа из входящих данных в таблицу, в которой имеются строки, при условии, что существует вероятность конфликта значений первичного ключа.