Перетворення даних xml в формат sql застосування функції sqlxml bulkload в структурі

У цій статті докладно описується функція SQLXML Bulkload на прикладі створення програми, що забезпечує перетворення вхідних даних XML в реляційні таблиці SQL Server. Ми також спробуємо відповісти на типові питання, що виникають при використанні функції Bulkload в корпоративному додатку. Зокрема, ми обговоримо наступні теми:

  • Перетворення складної ієрархії XML в одну таблицю.
  • Застосування функції Bulkload в додатку .NET.
  • Використання класів Stream як механізм введення даних для функції Bulkload в .NET.

Завдання: збереження вмісту RSS-каналів в SQL Server

У цій статті я продемонструю створення додатка, що приймає дані по технології RSS (Really Simple Syndication) і зберігає потрібну інформацію в реляційної базі даних. RSS - це формат XML, застосовуваний для доставки новин, а також інших інформаційних даних з деяких джерел. Рішення даного завдання включає два аспекти. По-перше, нам потрібно механізм для перетворення вхідних даних XML в реляційні таблиці і стовпчики. Формат XML визначено заздалегідь, і нам не потрібно поміщати в базу даних всю інформацію, отриману з каналу. По-друге, потрібно реалізувати передачу вхідних даних безпосередньо на сервери. Ці завдання вирішити, використовуючи схему перетворення і функцію Bulkload в SQLXML.

Зазначена задача є типовою для бізнес-систем, де вхідні дані представлені в формі XML, а в якості серверного сховища використовується реляційна база даних. Джерелом вхідних XML-даних можуть бути веб-служби, інші XML-повідомлення від зовнішніх бізнес-партнерів або джерела всередині самої компанії.

Короткий вступ в анотовані схеми SQLXML

Схеми XSD часто використовуються для опису вмісту і структури XML-даних, отже, можна створити XSD-схему, яка описує структуру RSS-каналів. У нашому додатку ми не будемо створювати XSD-схему для загальних RSS-каналів, а зосередимо увагу на підмножині структури XML, що використовується більшістю каналів. Канал, який використовували при написанні цієї статті, заснований на Yahoo! News RSS Feed (EN). Нам необхідно анотувати XSD-схему за допомогою реляційних метаданих, які застосовуються в SQLXML для перетворення XML-коду в формат реляційної БД. Ознайомтеся з анотованої схемою, що використовується для нашого застосування.

Лістинг 1. Анотована схема, яка використовується для нашого застосування

Наведена вище XSD-схема містить анотації реляційних даних, необхідні для перетворення. Все анотації перетворення, які стосуються SQLXML, належать простору імен xmlns: sql = "urn: schemas-microsoft-com: mapping-schema". Найбільш важливими є анотація sql: relation елемента item і різні анотації sql: field, що відносяться до його дочірнім елементам. Анотація sql: relation забезпечує перетворення елемента item в таблицю NewsFeed, а анотація sql: field - перетворення дочірніх елементів в стовпці цієї таблиці. Атрибути елемента також можна перетворювати в стовпці таблиці. Насправді анотація sql: field є необов'язковою, оскільки відображення «таблиця-елемент» охоплює всі дочірні елементи і атрибути даного елемента. У наведеній вище XSD-схемі тільки елементи isPermaLink і pubDate забезпечені анотацією sql: field, оскільки імена відповідних стовпців відрізняються. До іменам інших елементів застосовуються стандартні правила перетворення: вони автоматично перетворюються в однойменні стовпці.

У той же час RSS-канал включає безліч інших елементів, таких як channel, ttl і image, які в нашому випадку не потрібно перетворювати в формат реляційної бази даних. Для вирішення цієї проблеми в SQLXML можна використовувати анотації sql: is-constant або sql: mapped.

Анотація sql: is-constant в основному використовується для створення елементів-обгорток, які не відображаються в базу даних. У нашому випадку елементи rss і channel є елементами-обгортки в RSS-каналі, тому для них використовується анотація sql: is-constant. При використанні анотації sql: is-constant необхідно брати до уваги наступне. По-перше, вона може застосовуватися тільки до елементів складного типу. По-друге, якщо постійний (constant) елемент має атрибутами, ці атрибути не можуть бути перетворені в стовпці бази даних.

Анотація sql: mapped дозволяє явно вказати, що елемент або атрибут не потрібно перетворювати в будь-які об'єкти реляційної бази даних. Ця інструкція кілька разів використовувалася в схемі. Я помітив атрибут version анотацією sql: mapped = "false" явним чином, оскільки він є частиною постійного елемента. Я також анотований за допомогою sql: mapped = "false" все дочірні елементи channel, що мають простий тип. Цю анотацію я також використовую для елемента image. Необхідно відзначити, що image - це елемент складного типу, тому, анотований його, я запобіг перетворення самого цього елемента, а також всіх його дочірніх елементів і атрибутів. Анотацію sql: mapped можна використовувати як для елементів простого, так і для елементів складного типу. В останньому випадку всі дочірні елементи і атрибути, що входять до складу складного типу, також отримують значення анотації sql: mapped.

Перевага використання схеми перетворення для відображення вхідних XML-даних в базу даних полягає в тому, що один і той же відображення можна використовувати як для запитів до бази даних, так і для генерування різних XML-уявлень даних. Для цих цілей в SQLXML передбачена функцію XPath.

Використання Bulkload з керованого коду

Функція SQLXML Bulkload дозволяє завантажувати вхідні дані XML в реляційну базу даних. Ця функція використовує процес bcp сервера SQL Server і є оптимальним механізмом для завантаження великих обсягів вхідних XML-даних на сервер. Функція реалізована як COM-об'єкт і використовує постачальників SQLOLEDB. Завдяки цьому її зручно використовувати при програмуванні через ActiveX Data Objects (ADO), а також при використанні мов сценаріїв, наприклад VBScript. У нашому випадку функція Bulkload використовується в додатку .NET. Для реалізації цієї функції можна скористатися одним із зазначених нижче способів:

  • використовувати програму tlbimp.exe (EN). щоб імпортувати визначення типів COM в runtime-збірку, а потім додати сгенерированную Interop-збірку в проект;
  • додати в проект Visual Studio.NET посилання безпосередньо на DDL-бібліотеку Bulkload (xblkld3.dll). При цьому буде створена Interop-збірка, яку можна використовувати в проекті.

Після виконання будь-якої з наведених процедур використання Bulkload не складає особливих труднощів:

Лістинг 2. Використання Bulkload

Завантаження бази даних за допомогою SQLXML Bulkload

Я продемонструю два варіанти вирішення цієї проблеми. В обох випадках я використовую інтерфейс UCOMIStream (EN). в якому є кероване визначення інтерфейсу IStream. У першому варіанті застосовується об'єкт-оболонка потоку, який реалізує інтерфейс UCOMIStream. Нижче наведено приклад реалізації даного інтерфейсу:

Лістинг 3. Об'єкт-оболонка потоку, який реалізує інтерфейс UCOMIStream

Як видно з наведеного фрагменту коду, це не повна реалізація інтерфейсу UCOMIStream. Для функції Bulkload потрібно реалізувати тільки такі методи: Read, Write, Stat і Seek. Можна передати клас UCOMStreamWrapper безпосередньо методу Execute в Bulkload. Наведене вище рішення є ефективним способом передачі потокових даних функції Bulkload в додатку .NET.

Нижче наведено альтернативне рішення, яке не потребує реалізації інтерфейсу UCOMIStream.

Лістинг 4. pешение, яке не потребує реалізації інтерфейсу UCOMIStream

Недоліком даного рішення є те, що це не дуже раціональний спосіб передачі потоків в функцію Bulkload. Проблема полягає в використанні функції CreateStreamOnHGlobal, яка кешируєт дані в пам'яті і викликає зниження продуктивності.

У переданому коді для цієї статті є зразки кожного з наведеного вище рішень у вигляді окремих проектів.

Важливо відзначити, що при використанні ADO або мови сценарію можна безпосередньо передати потік ADODB.Stream функції Bulkload. У документації по SQLXML наведено приклад передачі потоку в середовищі VBScript.

Об'єктна модель Bulkload

Об'єктна модель Bulkload включає безліч властивостей, що забезпечують додаткову гнучкість і функціональність. Я використовував властивості ErrorLogFile і KeepIdentity. Якщо вказано властивість ErrorLogFile, функція Bulkload в процесі обробки реєструє будь-які помилки і попередження у відповідному файлі. Властивість KeepIdentity використовується для настройки ідентифікують стовпців. У нашому додатку стовпець ID є ідентифікує, і, якщо для властивості KeepIdentity задано значення false, Bulkload використовує значення ідентифікації, які генеруються SQL Server. Щоб використовувати в цілях ідентифікації дані з джерела, задайте для властивості KeepIdentity значення true (встановлено за умовчанням).

SchemaGen - ще одна цікава властивість, яке не використовується в моєму додатку, але може виявитися дуже корисним. З його допомогою можна генерувати серверні таблиці в базі даних до початку процесу завантаження. Bulkload використовує імена елементів і атрибутів, а також відомості про їх типах з XSD-схеми для генерування відповідних таблиць і стовпців. Властивість SchemaGen не створює обмежень для таблиць, однак якщо для властивості SGUseID задано значення true, а первинний ключ визначено з типом XSD ID, ці відомості використовуються для генерування первинного ключа. Дана властивість також використовує при зіставленні анотацію sql: relationship для генерування обмежень зовнішніх ключів. Додаткові відомості про всі властивості, які використовуються Bulkload, см. В документації, включеної в поставку SQLXML.

висновок

У цій статті я показав, як використовувати функцію Bulkload з SQLXML для заповнення бази даних вхідними даними формату XML. Реляційні дані можна потім без праці запитувати за допомогою таких технологій, як ADO.NET, що продемонстровано в додатку, яке доступне для завантаження. Функцію Bulkload можна використовувати як через звичайні засоби ADO, так і в додатках на мовах сценаріїв. Вона також може використовуватися в середовищі .NET через механізм COM Interop. У статті були показані гнучкі можливості по перетворенню складної ієрархії XML в просту схему бази даних за допомогою схеми перетворення.

Схожі статті