XML Web-служби в Microsoft SQL Server 2005

Олексій Ширшов

Компанія Microsoft робить все, щоб перетворити SQL Server у повноцінний
сервер додатків, який на сьогодні не може вважатися таким без підтримки
XML Web-служб. Можна сказати, що подібна підтримка була присутня в SQL Server
2000 з моменту виходу пакету Microsoft SQLXML 3.0, проте з тих пір пройшло
чимало часу, а розвиток технологій, пов'язаних з Web-службами, йшло дуже
активно. SQL Server 2005, або Yukon, представляє революційні нововведення як в
області підтримки XML на рівні процесора бази даних, так і в області
Web-служб.



Це далеко не повний список відмінностей від SQLXML 3.0, в даній статті я розповім
і про інших.


Навіщо базі даних XML


Почнемо з того, що XML призначений для розмітки даних, а кращого місця для
зберігання та обробки даних, ніж база даних, важко уявити. Зберігати
документи XML в базі даних в принципі можна було з самого моменту появи
XML, але що стосується обробки – тут все складніше. Так як документи XML
зберігалися в базі даних у вигляді об'єктів CLOB – Character Large Object, працювати
з ними на сервері саме як з документами XML було надзвичайно складно. Раз вже у
нас немає можливості нормально працювати з документами XML на сервері, давайте і
не будемо з ними працювати як з документами XML взагалі, а будемо їх
перетворювати до реляційному увазі і зберігати у звичайних таблицях. Такий метод
існує і навіть у певних випадках є оптимальним, однак він погано
застосуємо до неструктурованих або слабоструктуріруемим документами XML. У тому
випадку коли у нас є чітко формалізована модель документа XML, досить
просто перетворити її до реляційному увазі, однак коли заздалегідь невідомо,
якої структури будуть документи XML, що зберігаються в базі даних, зробити це
практично неможливо. Мені можуть заперечити, що дані з невизначеною
структурою взагалі не варто обробляти на сервері. Це дійсно так, і,
якщо вам потрібно просто зберігати якісь документи XML, неважливо що містять,
кращого методу, ніж CLOB, не знайти. Але найбільш поширені випадки, коли
модель документа XML описана лише частково: документ може містити різні
елементи розширення, це можуть бути документи нових версій даного формату з
новими елементами / атрибутами і т. д. На сервері можуть з'являтися додаткові
збережені процедури (або можуть змінюватися існуючі) для роботи з новими
елементами документа XML, і тут-то і виникає необхідність у наявності
певних механізмів роботи з XML на сервері.


Відповідно до вимог часу, в SQL Server 2000 з'явилася функція
openxml, яка дозволяла перетворювати рядок в документ XML і представляти
результат у вигляді таблиці. Однак даний метод мав певні недоліки,
пов'язані з простотою використання, продуктивністю і т. д., які мали
одне просте пояснення: XML – особливий тип даних, що має власні методи
обробки (XPath), і не потрібно намагатися емулювати їх за допомогою реляційної
алгебри.


Тому в Yukon і з'явився новий вбудований тип XML, вбудований процесор
мови XML, що підтримує не просто XPath 1.0, а частково XPath 2.0 і XQuery.
Тепер можна відповісти на запитання, які саме переваги ви отримуєте від
використання типу XML в Yukon.



Навіщо Yukon потрібні Web-служби


Альтернативою розробки Web-служб в Yukon є створення Web-служб
призначеними для цього засобами, Visual Studio наприклад. NET (ASP.NET
Web-служби або WSE 2.0). Незважаючи на те, що практично весь бізнес-логіку
тепер можна розмістити в SQL Server, краще все-таки не використовувати можливість
створення Web-служб в Yukon як механізму взаємодії зовнішніх компонентів з
системою. І не тому, що в Yukon є проблеми з безпекою, відсутня
гнучка настройка або це буде непродуктивно. Просто простіше, вигідніше,
ефективніше і правильніше створювати Web-служб із використанням Visual Studio
.NET.


Навіщо ж у Yukon надається можливість створення Web-служб? Справа в тому,
що механізм кінцевих точок (endpoints), на яких побудована підтримка
Web-служб в Yukon, широко використовується іншими підсистемами: Service Broker,
Database mirroring. Можливість виклику збережених процедур або пакетів команд
через цей механізм є незначною надбудовою, яка просто
відкриває новий шлях взаємодії в SQL Server. Іншими словами, усувається
монополізм бінарного протоколу спілкування з SQL Server, TDS (Tabular Data Stream).
Тепер ви можете, не відкриваючи портів SQL Server на proxy-сервері, віддалено
адмініструвати сервер через http / https. Це чудова і дуже потужна
можливість. Я не здивуюся, якщо найближчим часом з'явиться аналог Query
Analizer, побудований з використанням Web-служб.


Сподіваюся, мені вдалося трохи прояснити ситуацію з приводу питання, що стоїть в
заголовку даного розділу, а тому пропоную перейти до конкретних технічних
аспектам підтримки XML в Yukon.


Опис кінцевих точок


Як я вже сказав, механізм кінцевих точок є частиною ядра Yukon, хоча я
можу припустити, що ця концепція не була закладена спочатку. На жаль, у
мене зараз немає можливості встановити першу бета-версію, яка стала
доступна близько року тому (на виставці PDC 2003), однак я не пригадую, аби в
BOL тій версії згадувалися кінцеві точки. Більш того, там не було команди
create endpoint, замість неї була команда create http endpoint, яка, як
можна здогадатися, створювала кінцеву точку по протоколу http. За останній рік
фахівці Microsoft дуже сильно переробили механізм кінцевих точок, який
перетворився в основу взаємодії SQL Server із зовнішнім світом. Під'єднуючись з
допомогою Query Analizer або SQL Server Management Studio до Yukon, ми використовуємо
відповідну кінцеву точку протоколу TCP, яка дозволяє виконувати
команди TSQL.


Кінцеві точки


Синтаксис команди create endpoint досить складний, тому я розіб'ю його на
частини, кожну з яких буду описувати окремо. Базовий синтаксис такий:


CREATE ENDPOINT endPointName [AUTHORIZATION <login>]
STATE = {
STARTED | STOPPED | DISABLED }
AS {транспорт} (
<Специфічні для
даного транспорту налаштування>
)
FOR {протокол} (

<Специфічні для даного протоколу налаштування>
)



Формат для протоколу TSQL в поточній версії BOL не вказується, тому його ми
розглядати не будемо, так само як і протоколи для Service Broker і
DATABASE_MIRRORING. Також я не буду описувати транспорт TCP, так як він не може
використовуватися для протоколу SOAP, тому обмежимося тільки транспортом HTTP і
протоколом SOAP (до речі, у них найскладніші налаштування).


Окремо варто підкреслити, хоча це повинно бути видно з синтаксису, що
Web-служба може містити один Web-метод і більше або не містити Web-методів
взагалі, і при цьому успішно працювати (у разі, коли дозволені пакети
команд).


Природно, що після створення кінцевої точки вам напевно буде потрібно
змінювати її властивості. Як і багато інших об'єктів SQL Server, кінцеві точки
підтримують команду alter для зміни багатьох, але, прошу зауважити, не всіх
своїх параметрів. Синтаксис цієї команди не сильно відрізняється від команди create
endpoint, тому його ми розглядати не будемо.


Отримати список всіх кінцевих точок можна за допомогою системного уявлення
sys.endpoints. Воно повертає саму загальну інформацію про всі кінцевих точках.
Якщо вам потрібно отримати докладну інформацію, наприклад про Web-службах, можна
скористатися поданням sys.http_endpoints. Відповідно, для кінцевих
точок протоколу TCP необхідно задіяти sys.TCP_endpoints. Список
виключених для використання даної кінцевою точкою адрес можна переглянути в
системному представленні sys.ip_exceptions.


При створенні кінцевої точки можна зіткнутися з такими проблемами.



В якості «джерел» для Web-методів можна використовувати не тільки
власні збережені процедури або функції, але і системні. Щоправда, тут можуть
виникнути певні проблеми, пов'язані з тим, що не у всіх системних
збережених процедур є інформація про метаданих, яка необхідна для
формування wsdl-документа, тому без особливих налаштувань із подібними процедурами
працювати не можна. Варіанти налаштувань наступні.



Права доступу


Глибоко продумана система розмежування прав доступу в Yukon дозволяє
дуже гнучко налаштовувати рівень безпеки для будь-якого об'єкта бази даних, в
тому числі і кінцевих точок. Для кінцевих точок можна настроювати такі права
доступу.



Власник (owner) кінцевої точки і користувач у ролі sysadmin мають всі
права на кінцеву точку.


Синтаксис команди розмежування прав доступу (у скороченому варіанті)
такий:


{GRANT/DENY/REVOKE}
{CREATE/ALTER ANY/ALTER ON/CONNECT ON/TAKE
OWNERSHIP ON}
ENDPOINT TO <login>



Наведу приклад надання права на зміну параметрів кінцевої точки
HelloFromYukon для облікового запису test:


grant alter on endpoint::HelloFromYukon to test


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


Безпека і аутентифікація


До забезпечення безпеки розробники Yukon повинні були підійти особливо
уважно: у наш час факт злому якої б то не було системи визначається
тільки часом. Web-служби з точки зору безпеки є додатковою
можливістю атаки для хакерів, тому без розробки особливих заходів
обережності тут просто не обійтися. Які ж засоби для забезпечення
безпеки має Yukon?



Наріжним каменем безпеки є аутентифікація – процес передачі та
перевірки посвідчення користувача. Під посвідченням звичайно розуміють ім'я
користувача та пароль, хоча це можуть бути smart-карти, відбитки пальців і т.д.
Конфіденційність паролів жодним чином не повинна піддаватися ризику, тому
в Yukon для протоколів, які до перехоплення паролів нестійкі, використання
шифрування на транспортному рівні за допомогою ssl є обов'язковим. Це,
безумовно, створює деякі проблеми для користувачів Web-служби і ускладнює
підтримку, однак істотно знижує ризик перехоплення посвідчень.


Нижче наводяться типи аутентифікації, які підтримуються кінцевими точками
в Yukon.



Крім налаштування типу аутентифікація на рівні кінцевої точки, у нас є
можливість налаштувати тип облікового запису на рівні кожного окремого
Web-методa. Тип облікового запису може бути наступним.



Отже, перелічимо дії, які необхідно вжити адміністратору,
щоб дозволити викликати метод hello_world нашої Web-служби HelloFromYukon
користувачеві домену vasja.



  1. Створити обліковий запис на сервері: create login [domain \ vasja] from
    windows.
  2. Створити обліковий запис користувача в тестовій базі даних для облікового
    запису сервера: create user vasja for login [domain \ vasja].
  3. Надати право на виконання збереженої процедури hello_world: grant
    execute on hello_world to vasja.
  4. Надати право на з'єднання з даною кінцевою точкою: grant connect
    on endpoint::HelloFromYukon to [domain\vasja]

Опис SOAP-повідомлень


Якщо ви не любите копирсатися в деталях, не визнаєте SOAP і плануєте писати
клієнтські програми тільки за допомогою Visual Studio. NET, яка приховує
використовувані при обміні з сервером формати шляхом генерації proxy-класу, цей
розділ не для вас. У ньому ми будемо розглядати структуру SOAP-запитів і
SOAP-відповідей, допустимі заголовки і зміст wsdl-документа. Так як багато чого в
Yukon (принаймні, у цій версії) в області форматів повідомлень було взято
без будь-яких серйозних змін з пакету SQLXML, раджу перш ознайомитися
з відповідною документацією.

Структура повідомлень


Треба сказати, що опису вхідних і вихідних повідомлень у вигляді XML Schema
були істотно перероблені з точки зору збільшення строгості. Так,
наприклад, якщо в SQLXML були присутні всього три схеми в wsdl-документі, то в
Yukon їх кількість зросла до дев'яти. Природно, при цьому wsdl-документ став куди
більш громіздким і складним для сприйняття. При описі форматів повідомлень я буду використовувати
загальноприйняту систему кваліфікаторів множин вузлів, де: + – один і більше, * –
нуль і більше,? – Нуль або один, якщо нічого не вказано – рівно один.


Заголовки


Будь-яке SOAP-повідомлення може мати заголовки. Заголовки – це елементи в
розділі SOAP: Header SOAP-повідомлення. Заголовки різних типів описують аспекти
SOAP-повідомлення, тобто інформаційні елементи, які безпосередньо не відносяться до
основного інформаційного змісту повідомлення. Заголовки обробляються
незалежно від повідомлення, вони не впливають на те, що буде зроблено, але управляють
тим, як це буде зроблено.


Заголовки SOAP-повідомлень в Yukon введені в першу чергу для надання
додаткової інформації про клієнта, подібної до тієї, що надається
протоколом TDS. Всі розглянуті нижче елементи знаходяться в просторі імен
http://schemas.microsoft.com/ sqlserver/2004/SOAP/Options, схема якої може
бути отримана з wsdl-документа web service.


WSDL


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


WSDL-файли в чому спираються на схеми XSD, які ми розглянули в
попередньому розділі. У даному розділі будуть розглянуті особливості підтримки
WSDL в Yukon.


Навіщо взагалі можуть знадобитися WSDL-документи? Якщо має формувати
пакети SOAP вручну, по суті, вони і не потрібні. Однак подібний підхід до
використання Web-служб можна вважати неправильним. У XXI столітті прийнято застосовувати
засоби автоматичної генерації пакетів SOAP, які дозволяють задіяти
Web-служби як звичайні об'єкти в пам'яті програми. До подібних засобів можна
віднести генератор клієнтського посередника, що входить в. NET Framework, SOAP
Toolkit, генератор клієнтського посередника ATL та інші. Для них WSDL-документи
є обов'язковими. WSDL-документ надає всю необхідну інформацію
для генерування коду і успішної взаємодії з Web-службою, а саме:
використовувані протоколи, фізичні адреси і порти, доступні методи, параметри і
типи параметрів цих методів і багато ін Якщо ви розробляєте власну
Web-службу, підтримка WSDL на сьогодні фактично вважається обов'язковою.


Використання Web-служби


Оскільки архітектура Web-служб заснована на відкритих стандартах, при коректній
реалізації серверного коду клієнтами Web-служби в ідеалі може бути хто завгодно.
На практиці клієнтські засоби доступу до Web-службі завжди володіють
певними недоліками. Хоча подібних недоліків у стандартному генераторі
клієнтського коду. Net Framework 1.1 небагато, на жаль, він практично не
може використовуватися з Web-службами Yukon. У даному розділі я розгляну
особливості роботи з Web-службами за допомогою Visual Studio. NET 2003, SOAP
Toolkit і Visual Studio. NET 2005. Найменше проблем виникає з Visual
Studio. NET 2005 (хоча я використовував тільки бета-версію), з неї і почнемо.


Visual Studio .NET 2005


Генератор клієнтського коду Visual Studio. NET 2005 прекрасно працює з
WSDL-файлом Yukon. Послідовність дій така. За допомогою діалогового
вікна Add Reference або утиліти wsdl.exe ми генеруємо клієнтський код, далі
створюємо екземпляр proxy-класу, присвоюємо його властивості Credentials
відповідне значення (це обов'язково) і викликаємо Web-метод.


Необхідно врахувати, що при використанні простого WSDL-документа результати
вибірки будуть представлені у вигляді масиву екземплярів типу XMLElement, а
скалярні значення – у вигляді примірників шаблону System.Nullable (of T). При
використанні складного WSDL-документа результати вибірки будуть представлені в
вигляді масиву об'єктів типу System.Data.DataSet – містить власне дані,
Integer – містить результуючий код (елемент SqlResultCode) і SqlRowCount –
містить кількість вибраних рядків. Скалярні значення будуть представлені
екземплярами з простору імен System.Data.SqlTypes.


Якщо ви вказали аутентифікацію MIXED при створенні кінцевої точки, тоді вам
необхідно передавати з кожним SOAP-запитом інформацію про посвідчення
користувача у вигляді SOAP-заголовка – Security. Цей заголовок є частиною
специфікації WS-Security; використовуючи механізм XML серіалізациі, створити його
досить просто (приклад реалізації даного заголовка за допомогою IXMLSerializable
можна знайти в BOL).


Для використання заголовка необхідно змінити стандартний код, що генерується
середовищем розробки: потрібно додати до proxy-класу елемент типу Security, вказати
атрибут SOAPHeader для методів proxy-класу, в конструктор якого передати
назва елемента заголовка. Після створення екземпляра proxy-класу, але перед
викликом відповідного методу, необхідно заповнити поля цього заголовка. Тип
пароля –
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0 # PasswordText


Крім цього, тому що необхідно використовувати SSL для аутентифікації MIXED,
потрібно статичному властивості Net.ServicePointManager.CertificatePolicy
присвоїти примірник наступного класу:


Friend Class MyCertValidation
Implements Net.ICertificatePolicy

Public Function CheckValidationResult(ByVal srvPoint As
System.Net.ServicePoint,
ByVal certificate As System.Security.Cryptography

.X509Certificates.X509Certificate,
ByVal request As
System.Net.WebRequest, ByVal certificateProblem As Integer) As
Boolean
Implements System.Net.ICertificatePolicy.CheckValidationResult
Return True

End Function
End Class


Даний клас перевизначає всього одну функцію, яка повертає true. Це
дозволяє використовувати сертифікати SSL, які не є довіреними.


Visual Studio .NET 2003


У старій версії середовища розробки справи з використанням Web-служб Yukon
йдуть гірше. . Net Framework 1.1 не вміє працювати зі складною версією
WSDL-документа SQL Server 2005. При генерації самого proxy-класу помилок не
виникає, однак при його створенні ініціюється виняток – «Method couldn't be
reflected ». Єдина можливість працювати з Web-службою полягає в
використанні простого WSDL-документа. Однак і тут все не так просто.
Скалярні методи викликаються чудово, але методи, які повертають набір рядків,
представляють результати у вигляді об'єктів типу XMLDocument. Для набору рядків
XMLElement містить XML у форматі diffgram, який, однак, не може
використовуватися для створення DataSet. Справа в тому, що формат вбудованої схеми,
яка повертається разом з набором, незрозумілий класу DataSet з. NET
Framework 1.1 і нижче. Відмовитися від генерації вбудованої схеми можна (див.
синтаксис команди create endpoint), але формат diffgram влаштований таким чином,
що наявність інформації про схему даних для нього є обов'язковим. Вихід з
ситуації тільки один – самому вручну або автоматично створювати схему для
DataSet на клієнті.


Звичайно, це не самий зручний і правильний метод. При будь-яку зміну в
Web-методі доведеться змінювати код клієнта, щоб структура DataSet відповідала
відповідній структурі результуючого набору рядків. Однак, якщо структура
повідомлень змінюватися не буде, можна згенерувати типізований DataSet, і
тоді робота з результатами виклику Web-методу стане істотно простіше.


SOAP Toolkit


SOAP Toolkit не має стандартних конвертерів, які дозволяли б працювати
зі складним WSDL-документом Yukon. Знову ж у даній ситуації може допомогти
простий WSDL-документ.


Як можна бачити з коду, гідності сценаріїв, що використовують SOAP Toolkit,
полягає в тому, що не потрібно попередньо генерувати proxy-клас – весь
код інфраструктура створює «на льоту», у момент виклику методу mssoapinit. З
іншого боку, ми втрачаємо строгу типізацію, тому результуючий
SOAP-документ представлений у «сирому» вигляді – у якості об'єктів DOM. Для
подальшої роботи з результатами потрібно використовувати відносно складний
шлях написання XPath-запитів. Однак для тестування я вважаю цей метод
ідеальним.


Заголовки в SOAP Toolkit, які можуть знадобитися для авторизації, сесій
або транзакцій, можуть бути додані за допомогою реалізації інтерфейсу
IHeaderHandler. Приклади відповідного коду можна знайти в MSDN.


Сесії


Архітектура Web-служб у чистому вигляді є stateless, тобто не має
стану. Однак багато інфраструктури нібито ASP.NET Web Services дозволяють
створювати statefull (що мають стан) Web-служби. Web-служби Yukon також можуть
зберігати стан, проте з точки зору архітектури їх відміну від ASP.NET Web
Services полягає в тому, що Yukon зберігає ідентифікатори сесій у заголовках
SOAP-пакетів, а не в cookies.


Сесія є внутрішнім, ядерним об'єктом сервера. Список усіх сесій
можна переглянути за допомогою динамічного подання sys.dm_exec_sessions.
Час життя сесії може бути заданий за створення кінцевої точки. За замовчуванням
воно складає 60 секунд. Створення сесії проводиться за допомогою посилки
заголовка SQLSession:


<sqloptions:sqlSession initiate=»true»/>


де sqloptions префікс простору імен http://schemas.microsoft.com/
sqlserver/2004/SOAP/Options.


Після цього сервер поряд зі звичайними результатами вибірки повертає той же
самий заголовок, але вже з атрибутами sessionId – ідентифікатор сесії і timeout
– Час життя сесії. Ідентифікатор сесії кодується у форму base64 і в
надалі використовується при наступних запитах. Ідентифікатор сесії суворо
прив'язаний до облікових даних клієнта Windows, який ініціював сесію.
Забороняється використовувати той же самий ідентифікатор під іншими обліковими
даними. Сесія дійсна до тих пір, поки не закінчиться час її життя або
поки клієнт сам не завершить її. Завершення сесії досягається шляхом посилки
заголовка SQLSession з атрибутом terminate:


<sqloptions:sqlSession terminate=»true»
sessionId=»eAV9/GUw2U6g/89aUWzp4g==»/>


Запит на завершення сесії може не містити нічого, крім заголовка. Якщо
сервер успішно закриває сесію, він надсилає повідомлення, з точно таким
же заголовком і точно такими ж значеннями атрибутів.


Для використання сесій у своєму додатку доведеться формувати заголовок
SQLSession самостійно. У разі SOAP Toolkit, як я вже говорив вище, це
можна зробити за допомогою інтерфейсу IHeaderHandler. Для Visual Studio всі
значно простіше: у BOL є приклад даного заголовка.


Транзакції


Транзакційний виклик Web-методів – це дуже потужна можливість, що дозволяє
позбавитися від багатьох проблем при реалізації бізнес-логіки. Реалізація транзакцій
в Yukon для кінцевих точок SOAP має деякі обмеження.



Для початку транзакції необхідно ініціювати сесію, передати заголовок
environmentChangeNotifications і власне почати транзакцію (просту або
розподілену) в коді TSQL пакетного запиту.


У даному пакетному запиті ми відкриваємо транзакцію, вибираємо всі рядки з
таблиці test бази даних test, говоримо, що необхідно почати нову сесію, а
також повідомляємо серверу про те, що хочемо отримувати всі дані про зміну
контексту транзакції. На подібний запит сервер повинен повернути, крім
результатів вибірки та заголовка сесії, ще й структуру SqlTransaction всередині
елемента sqlbacthResult приблизно такого змісту:


<sqlresultstream:SqlTransaction
xsi:type=»sqltransaction:SqlTransaction»>

<sqltransaction:Descriptor>
AQAAADkAAAA=</sqltransaction:Descriptor>

<sqltransaction:Type>Begin</sqltransaction:Type>

</sqlresultstream:SqlTransaction>


де sqltransaction – префікс простору імен http://schemas.
microsoft.com / sqlserver / 2004/SOAP/types/SqlTransaction, значення текстового
вузла елемента Descriptor – ідентифікатор транзакції і тип повідомлення про
транзакції – Begin.


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


Приєднатися до існуючого контексту транзакції можна за допомогою атрибуту
transactionDescriptor елемента sqlSession, значення якого є
ідентифікатором даної транзакції:


<Sqloptions: sqlSession sessionId = »jGqn3/X73EGHjFxZ12zovw ==
»transactionDescriptor=»AQAAADMAAAA=»/>


Завершити транзакцію можна двома способами: або підтвердити (commit) її,
або скасувати (rollback). В обох випадках сервер повинен надіслати відповідь
повідомлення з елементом SqlTransaction, який би містив дескриптор транзакції
і відповідний тип: при скасуванні транзакції – rollback, при підтвердженні –
commit. Крім цього, транзакція може бути скасована при закритті сесії.


Транзакції (як і сесії і інші заголовки) необхідно задавати
самостійно. У BOL є приклади подібних заголовків з використанням
XML-серіалізациі.


Висновок


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



Опис транспорту HTTP


AS HTTP (

PATH = ‘url’
, AUTHENTICATION =( { BASIC | DIGEST | INTEGRATED } [,…n])

, PORTS = ({CLEAR | SSL} [,… n])
[ SITE = {‘*’ | ‘+’ | ‘webSite’ },]

[, CLEAR_PORT = порт для http]
[, SSL_PORT = порт для https]
[,
AUTH_REALM = { ‘realm’ | NONE } ]
[, DEFAULT_LOGON_DOMAIN = {‘domain’ | NONE
} ]
[, RESTRICT_IP = { NONE | ALL } ]
[, COMPRESSION = { ENABLED |
DISABLED } ]
[, EXCEPT_IP = ( { <4-part-ip> |
<4-part-ip>:<mask> } [,…n] )
)




Синтаксис для створення Web-служби


FOR SOAP(
[ { WEBMETHOD [ ‘namespace’ .] ‘method_alias’
( NAME =
‘three.part.name’
[, SCHEMA = {NONE | STANDARD | DEFAULT}]
[, FORMAT = {
ALL_RESULTS | ROWSETS_ONLY | NONE }]
[, LOGIN_ENGINE= { MIXED | WINDOWS } ]

)
} [,…n] ]
[ BATCHES = { ENABLED | DISABLED } ]
[ , WSDL = {
NONE | DEFAULT | ‘sp_name’ } ]
[ , SESSIONS = { ENABLED | DISABLED } ]
[
, SESSION_TIMEOUT = int ]


[ , DATABASE = { ‘database_name’ | DEFAULT }

[ , NAMESPACE = { ‘namespace’ | DEFAULT } ]
[ , SCHEMA = { NONE |
STANDARD } ]
[ , CHARACTER_SET = { SQL | XML }]
)




Опис структури повідомлень SOAP


Запит

Формат виклику Web-методу не змінився, однак у клієнта з'явилася нова
можливість виконувати пакетні команди. Структура запиту при цьому виглядає
так:


<env:Body>
<sqlbatch xmlns=»http://schemas.microsoft.
com/sqlserver/2004/SOAP»>
<BatchCommands> Будь TSQL
вираз </ BatchCommands>
<Parameters>
<SqlParameter
xmlns=»http://schemas.microsoft.com/
sqlserver/2004/SOAP/types/SqlParameter»>*
<Value/>

</SqlParameter>
</Parameters>
</sqlbatch>

</env:Body>


Атрибути елемента SqlParameter описують точні властивості параметра.



Значення параметра задається в елементі Value, який не має конкретного
типу за схемою XML. Його тип необхідно вказувати безпосередньо в повідомленні з
допомогою атрибуту xsi: type.


Елементи пакетної команди BatchCommands і Parameters повинні бути в
просторі імен http://schemas.microsoft.com/sqlserver/2004/SOAP. Елементи
SqlParameter і Value – у просторі імен http://schemas.microsoft.com/
sqlserver/2004/SOAP/types/SqlParameter.

Відповідь

Вам відповідь має більш істотні відмінності від SQLXML. У ньому може
з'являтися один або більше з наведених нижче об'єктів.



Ось як виглядає опис цих об'єктів у форматі схеми XML:


<xsd:complexType name=»SqlResultStream»>
<xsd:choice
minOccurs=»1» maxOccurs=»unbounded»>
<xsd:element name=»SqlRowSet»
type=»sqlsoaptypes:SqlRowSet»/>
<xsd:element name=»SqlXml»
type=»sqlsoaptypes:SqlXml»/>
<xsd:element name=»SqlMessage»
type=»sqlmessage:SqlMessage»/>
<xsd:element name=»SqlRowCount»
type=»sqlrowcount:SqlRowCount»/>
<xsd:element name=»SqlResultCode»
type=»sqlsoaptypes:SqlResultCode»/>
<xsd:element name=»SqlTransaction»
type=»sqltransaction:SqlTransaction»/>
</xsd:choice>

</xsd:complexType>


Як вже говорилося вище, в результуючому потоці з'явилося два нових
елементи: SqlRowCount і SqlTransaction. Загальна структура листа у відповідь
така:


<method:MethodNameResponse>
<method:MethodNameResult
xmlns=»»>
<! – Об'єкти простору імен sqlresultstream->

</method:MethodNameResult>

<method:OutputParam>Value</method:OutputParam>*

</method:MethodNameResponse>


Тут:



Елемент MethodNameResult може містити один або більше об'єктів, описаних в
типі SqlResultStream. Розглянемо, в яких випадках буде використовуватися той чи
інший об'єкт.


SqlRowSet – використовується у випадку, коли результуючий потік містить
результати реляційної вибірки. Цей елемент описаний у схемі так:


<xsd:complexType name=»SqlRowSet»>
<xsd:sequence
maxOccurs=»unbounded»>
<xsd:any
namespace=»http://www.w3.org/2001/XMLSchema»
minOccurs=»0»
processContents=»lax»/>
<xsd:any
namespace=»urn:schemas-microsoft-com:xml-diffgram-v1»
minOccurs=»0»
processContents=»lax»/>
</xsd:sequence>

</xsd:complexType>


Він може містити будь-яку кількість елементів з простору імен
http://www.w3.org/2001/XMLSchema, а також будь-яку кількість елементів з
простору імен urn: schemas-microsoft-com: xml-diffgram-v1. Перший простір
імен належить стандарту схеми XML і означає, що в результуючий потік
може включатися XSD-схема. Це поведінка регулюється за допомогою параметра
schema кінцевої точки і Web-методу. Друге простір імен означає, що
результуюча вибірка буде представлена у форматі diffgram, який
підтримується стандартним класом System.Data.DataSet з. Net Framework.
Наприклад, результатом виконання лістингу
буде наступна diffgram (несуттєві частині повідомлення видалені):


<diffgr:diffgram
xmlns:diffgr=»urn:schemas-microsoft-com:xml-diffgram-v1»>
<SqlRowSet1
xmlns=»urn:schemas-microsoft-com:sql:SqlRowSet1»>
<row>

<EmployeeID>10</EmployeeID>

<LoginID>adventure-works\barryj</LoginID>

<Gender>M</Gender>
</row>
</SqlRowSet1>

</diffgr:diffgram>


SqlXml – використовується у випадку, якщо застосовуються for xml-запити, які
повертають xml. Немає необхідності перетворювати результати цих запитів у
diffgram, тому що вони самі є xml-документи. Опис
елемента SqlXml представлено у схемі наступним чином:


<xsd:complexType name=»SqlXml» mixed=»true»>

<xsd:sequence>
<xsd:any/>
</xsd:sequence>

</xsd:complexType>


Елемент SqlXml може містити будь-який елемент з будь-якого простору імен. У
Як приклад візьмемо той же самий лістинг 2, тільки з трохи зміненим
запитом: наприкінці додамо for xml auto. Ось результат:


<SqlXml>
<HumanResources.Employee EmployeeID=»10»

LoginID=»adventure-works\barryj» Gender=»M»/>
</SqlXml>


SqlMessage – всі програмні помилки, не пов'язані з інфраструктурі кінцевих
точок, повертаються в даному елементі. Структура елемента досить проста,
тому її опис тут не наводиться. Непрограмне помилки описані в
наступному розділі.


Помилка

У більшості випадків Yukon не повертає помилки soap при наявності помилок у
запитах SQL, параметрах збережених процедур і т.д. Soap-помилки повертаються
тільки в наступних випадках.



У разі подібного роду помилок Yukon повертає 500-й код помилки http і
елемент env: Fault у відповідному SOAP-повідомленні. Soap-помилка повертається у форматі
soap 1.1, однак більш докладна інформація про помилку може бути отримана через
внутрішню структуру в форматі soap 1.2, що знаходиться в елементі detail.



Типи WSDL-файлів


Розглянемо фрагмент синтаксису створення і зміни кінцевої точки:


[ , WSDL = { NONE | DEFAULT | ‘sp_name’ } ]


При створенні кінцевої точки, якщо не задано жодних спеціальних параметрів
або вказано значення NONE, підтримка wsdl буде відключена. При вказівці значення
DEFAULT SQL Server 2005 буде використовувати стандартний генератор
wsdl-документів, який може створювати два типи документів: прості і складні.
Складний wsdl-документ описує всі деталі і тонкощі повертаються SQL Server
документів XML. У такому документі присутній велика XSD-схема, дуже
докладно описує всі серверні типи в форматі XSD. Получающаяся в результаті
XSD-схема настільки складна, що багато автоматичні засоби генерації
клієнтського коду не можуть обробити подібний WSDL-документ. Як не дивно, до
таких засобів належать стандартний генератор. NET Framework 1.1 і SOAP
Toolkit. Для подібних «застарілих» коштів SQL Server генерує wsdl-документ у
простому форматі. Основна відмінність полягає в тому, що результуючий документ
XML має тип не SqlResultStream, а простий тип xsd: any.


Ось фрагмент простого wsdl-документа нашої Web-служби:


<xsd:element name=»hello_worldResponse»>
<xsd:complexType>

<xsd:sequence>
<xsd:element minOccurs=»1» maxOccurs=»1»
nillable=»false» name=»hello_worldResult»>
<xsd:complexType
mixed=»true»>
<xsd:sequence>
<xsd:any minOccurs=»0»
maxOccurs=»unbounded» processContents=»skip»/>
</xsd:sequence>

</xsd:complexType>
</xsd:element>
</xsd:sequence>

</xsd:complexType>
</xsd:element>


Як можна помітити, елемент hello_worldResponse містить лише один елемент
hello_worldResult, який може містити будь-яку кількість яких завгодно
елементів.


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


Складний wsdl-документ можна отримати шляхом звернення до Web-службі:
http://localhost/yukon/hello?wsdl. Дану рядок можна набрати в будь-якому браузері,
наприклад в Internet Explorer. Він завантажить WSDL-документ і відобразить його як
звичайний XML-файл. Для отримання простого документа необхідно звернутися до
сервера так: http://localhost/yukon/hello?wsdlsimple.


Всі документи генеруються «на льоту», тобто SQL Server не кешує їх і не
обчислює заздалегідь.


Якщо вас з яких-небудь причин не влаштовує стандартний генератор
wsdl-документів, ви можете написати свій. Користувальницький генератор – це
звичайна збережена процедура з певною сигнатурою, яка повинна повертати
набір з одним рядком і одним полем. Значення цього осередку буде трактуватися як
WSDL-документ. Сигнатура збереженої процедури така:


CREATE PROCEDURE <SP name>(
@endpointID as int,
@isSSL as
bit,
@host as nvarchar(256),
@queryString as nvarchar(256))

as


де:



Дана процедура викликається, коли відбувається звернення за адресою кінцевої
точки із зазначенням будь-якого параметра (параметр – це те, що йде після
знаку запитання в рядку запиту). Наприклад, для нашої Web-служби ми можемо
написати наступне: http://localhost/yukon/hello?some-info. Рядок після знака
питання (some-info) буде передана в збережену процедуру в якості параметра
queryString. З міркувань сумісності і наочності рекомендується починати
назва параметра зі слова wsdl, наприклад:
http://localhost/yukon/hello?wsdl,some-info.


Зазвичай подібні процедури, що зберігаються пишуться на керованому коді з
використанням всіх можливостей звичайних мов (таких, як VB.NET або C #) і
загальної мовного середовища – CLR. Приклад подібної процедури можна знайти в BOL, але
можна написати її з використанням простого TSQL.


Стандартні генератори схем, які можуть знадобитися при написанні
власного генератора, є також збереженими процедурами. Інформацію про них
можна переглянути за допомогою наступного запиту:


select * from sys.system_objects where name like
‘sp_http_generate_wsdl%’


Параметри системних збережених процедур можна переглянути за допомогою
подання sys.system_parameters. Сигнатури користувача функції
генератора я, до речі, дізнався з такого запиту:


select * from sys.system_parameters where [object_id] =
object_id(‘sp_http_generate_wsdl_defaultcomplexorsimple’)


Рекомендую виконати цей запит перед тим, як писати власний генератор,
тому що я сильно сумніваюся, що сигнатура збереженої процедури в майбутніх
версіях Yukon не зміниться.

Примітка автора.


Вся наведена в статті інформація відноситься до другої бета-версії SQL
Server 2005, тому третя бета-версія або фінальний продукт можуть відрізнятися
за функціональністю або деталей реалізації. Будьте уважні і звіряйтеся з
BOL.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*