XML в MS SQL Server 2000 и технологиях доступа к данным | SQL Server как Web-сервис | Дальше » |
Web-сервис - это компонент, к которому можно обращаться с
помощью XML. Результаты вызова метода также оборачиваются в
XML. Протокол устройства XML-сообщений, которыми обмениваются
клиент и Web-сервис, называется SOAP. В отличие от RPC и
других бинарных, зависимых от платформы протоколов,
ориентированных на плотное взаимодействие, SOAP
предусматривает работу в слабосвязанных средах (Интернет) и,
будучи основан на XML, позволяет общаться компонентам
независимо от операционной системе или инструмента разработки,
в которых они были созданы. Потребность в удаленном
взаимодействии компонентов через Интернет назрела давно. В
свое время HTML-формы и ASP превратили посетителя Web-узла из
пассивного зрителя, просматривающего заранее подготовленные
странички, в активного участника, формирующего страницу по
информации из базы на основе своих критериев. Однако эта
информация доставлялась потребителю по-прежнему в
HTML-формате, что, может быть, удобно с точки зрения
визуального восприятия, но никуда не годится, если вы хотите,
например, выцепить из полученной странички котировки акций,
превратить их в recordset и передать своему приложению.
Web-сервисы публикуют описания своих интерфейсов в wsdl-файлах
(аналог библиотеки типов в СОМ). Например, методу,
возвращающему котировки, нужно подать на вход интересующую
дату и биржевой символ. Чтобы найти подходящий Web-сервис или
выяснить назначение найденного, можно использовать
универсальный реестр UDDI и протокол DISCO. В Visual
Studio.Net входят средства создания как самих Web-сервисов,
так и клиентов, их использующих. Например, не составляет труда
создать Web-сервис, который будет принимать имя и параметры
хранимой процедуры на SQL Server, выполнять ее и отсылать
результаты клиенту. Словом, типичная трехуровневая
архитектура, только клиентская компонента, компонента
бизнес-логика и сервер теперь не ограничены пределами
локальной сети, а находятся где угодно в Интернете. Начиная с
SQLXML 3.0 в роли Web-сервиса может выступать SQL Server 2000,
так что надобность в промежуточной компоненте теперь отпадает.
Присутствие ПО промежуточного слоя наиболее часто оправдывают
требованиями безопасности, масштабируемости и
программируемости. Последние два, вероятно, наиболее честные,
потому что я с трудом понимаю, как толщина middleware может
влиять на устойчивость сервера к попыткам несанкционированного
проникновения. Если вы дыряво настроили политики безопасности
на сервере, то злоумышленник все равно на него придет
независимо от того, 5 шагов ему перед этим придется сделать
или 10. Вот программируемость - это уже серьезней. Т-SQL до
сих пор остается странной смесью мощи и ограничений.
Отсутствие многих обыденных для современных языков
конструкций, не говоря уже об ООП, приводило к тому, что народ
утешал себя тем, что SQL не для того предназначался, и уходил
писать логику на С++, Visual Basic, Delphi и т.д. В последнее
время круг задач, решаемых SQL Server, очень сильно расширился
за рамки пресловутого SQL, следовательно, возможности языка
программирования на серверной стороне, как бы он ни назывался,
должны им соответствовать. И они будут соответствовать в
следующей версии. Пункт третий - масштабируемость. С целью
повышения масштабируемости и распределения нагрузки в SQL
Server 2000, как известно, были введены распределенные
фрагментированные представления. Несмотря на то, что благодаря
этому механизму SQL Server занимает в настоящий момент первые
места в рейтингах производительности, следует понимать, что в
действительности это лишь первый этап на пути к базе данных,
автоматически распределяемой по многим серверам в сети, когда
каждый узел, получивший запрос, разбивает его на подзапросы к
тем серверам, где в действительности лежат нужные данные (а
если они продублированы, то к наименее загруженным). Таким
образом, понятно, что все три критерия обособления являются
достаточно условными, и не всегда компоненты бизнес-логики
будут выноситься за пределы SQL Server. Следовательно, тот
факт, что клиентское приложение сможет общаться с ним напрямую
как с Web-сервисом, на самом деле очень важен. Вернемся к
Скрипту 14. CREATE PROCEDURE CustomerOrdersForYear @Name nvarchar(20), @Year smallint AS SELECT c.ContactName, c.ContactTitle, o.OrderDate, o.Freight FROM Customers c INNER JOIN Orders o ON c.CustomerID = o.CustomerID WHERE c.ContactName like @Name + '%' and year(o.OrderDate) = @Year В качестве второго метода Web-сервиса выбираем шаблон из п.10 (рис.6). Он добавляется вызовом AddTemplateMethod. Параметрами служат внешнее имя метода, местоположение шаблона относительно данного скрипта и способ передачи ошибок (SOAP - да/нет). Результат шаблона можно передавать только как набор XML-элементов. Строка sqlWebSvc.SoapMethods.GenerateWSDL(); производит автоматическую генерацию wsdl-файла, который кладется в физическую директорию, соответствующую виртуальному подкаталогу типа soap. После этого Web-сервис становится доступным для обращений. Как и в классическом DCOM, на машине клиента нужно создать прокси, содержащего сигнатуру методов Web-сервиса. В графической среде разработки Visual Studio это происходит автоматически при добавлении ссылки на wsdl-файл в раздел Web References проекта. Прокси можно также сгенерировать с помощью утилиты командной строки wsdl.exe: wsdl.exe /l:CS /o:SQLSrvWebService_Proxy.cs /n:SQLSrvWebRef http://localhost/SQLXML3/websvc?wsdl В качестве параметров здесь передаются
язык, на котором будет создан прокси, имя файла с прокси, его
пространство имен и URI Web-сервиса с его описанием в виде
wsdl. Обращение клиента к Web-сервису показано в Скрипте 20.
static void SQLSrvWebService_Client() { SQLSrvWebRef.SQLSoapSample proxy = new SQLSrvWebRef.SQLSoapSample(); proxy.Credentials = System.Net.CredentialCache.DefaultCredentials; Console.WriteLine("----------------------------------------------------------------"); Console.WriteLine("Результаты выполнения шаблона (всегда как массив XML-элементов):"); object[] resultXml = proxy.ПримерВызоваШаблона("20", "1000"); foreach (XmlElement x in resultXml) Console.WriteLine(x.OuterXml); Console.WriteLine("\n----------------------------------------------------------------"); Console.WriteLine("Результаты выполнения хранимой процедуры (заказаны как DataSet):"); int retVal; DataSet resultRel = proxy.ЗаказыКлиентаЗаГод("Maria", 1997, out retVal); DataRelation rel = resultRel.Relations[0]; Console.WriteLine("\nТаблицы связаны отношением " + rel.RelationName); Console.Write("Родительская таблица " + rel.ParentTable.TableName + ", родительский ключ - "); foreach (DataColumn c in rel.ParentColumns) Console.Write(c.ColumnName + " "); Console.Write("\nДочерняя таблица " + rel.ChildTable.TableName + ", дочерний ключ - "); foreach (DataColumn c in rel.ChildColumns) Console.Write(c.ColumnName + " "); Console.WriteLine(""); foreach (DataRow rParent in rel.ParentTable.Rows) { Console.WriteLine("\nТаблица " + rel.ParentTable.TableName); foreach (DataColumn cParent in rel.ParentTable.Columns) Console.Write(cParent.Caption + ": " + rParent[cParent] + "; "); Console.Write("\n\tСвязанные записи из таблицы " + rel.ChildTable.TableName); foreach (DataRow rChild in rParent.GetChildRows(rel)) { Console.Write("\n\t"); foreach (DataColumn cChild in rel.ChildTable.Columns) Console.Write(cChild.Caption + ": " + rChild[cChild] + "; "); } Console.WriteLine(""); } } Результат выполнения шаблона получается в виде массива XmlElement, состоящего из единственного элемента, OuterXml которого показан ниже: <Солянка xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy" Title="Sales Re presentative" TitleOfCourtesy="Ms." ... /> <Customers ContactName="Horst Kloss" Кол-во="28" /><Customers ContactName="Jos e Pavarotti" Кол-во="31" /><Customers ContactName="Roland Mendel" Кол-во="30" /> <Клиент Имя="Horst Kloss" Фирма="QUICK-Stop" Должность="Accounting Manager"><А дрес><Страна>Germany</Страна><Город>Cunewalde</Город><Улица_дом>Taucherstra?e 10 </Улица_дом></Адрес><Заказы><Заказ Номер="10273"><Дата>1996-08-05</Дата><Стоимос ть>76.07</Стоимость></Заказ><Заказ Номер="10285"><Дата>1996-08-20</Дата><Стоимос ть>76.83</Стоимость></Заказ>...</Заказы></Клиент> <Сотрудник Фамилия="Fuller" Имя="Andrew"><Сотрудник Фамилия="Davolio" Имя="Nan cy" /><Сотрудник Фамилия="Leverling" Имя="Janet" /><Сотрудник Фамилия="Peacock" Имя="Margaret" /><Сотрудник Фамилия="Buchanan" Имя="Steven"><Сотрудник Фамилия=" Suyama" Имя="Michael" /><Сотрудник Фамилия="King" Имя="Robert" /><Сотрудник Фами лия="Dodsworth" Имя="Anne" /></Сотрудник><Сотрудник Фамилия="Callahan" Имя="Laur a" /></Сотрудник> </Солянка> DataSet как результат второго метода
состоит из двух таблиц: Customers и Orders. Выбор Row
Formatting = Nested на стадии определения метода Web-сервиса
приводит к тому, что условие соединения таблиц в запросе
(JOIN) переходит в свойство Relations объекта DataSet и
позволяет для каждого клиента выбрать сделанные им заказы:
Таблица Customers ContactName: Maria Larsson; ContactTitle: Owner; Customers_Id: 0; Связанные записи из таблицы Orders OrderDate: 03.02.1997 0:00:00; Freight: 17.92; Customers_Id: 0; OrderDate: 28.02.1997 0:00:00; Freight: 16.27; Customers_Id: 0; OrderDate: 12.05.1997 0:00:00; Freight: 188.04; Customers_Id: 0; OrderDate: 06.06.1997 0:00:00; Freight: 242.21; Customers_Id: 0; Таблица Customers ContactName: Maria Anders; ContactTitle: Sales Representative; Customers_Id: 1; Связанные записи из таблицы Orders OrderDate: 25.08.1997 0:00:00; Freight: 29.46; Customers_Id: 1; OrderDate: 03.10.1997 0:00:00; Freight: 61.02; Customers_Id: 1; OrderDate: 13.10.1997 0:00:00; Freight: 23.94; Customers_Id: 1; Таблица Customers ContactName: Maria Larsson; ContactTitle: Owner; Customers_Id: 2; Связанные записи из таблицы Orders OrderDate: 14.10.1997 0:00:00; Freight: 152.3; Customers_Id: 2; OrderDate: 02.12.1997 0:00:00; Freight: 328.74; Customers_Id: 2; OrderDate: 11.12.1997 0:00:00; Freight: 48.2; Customers_Id: 2; The program '[2460] ConsoleApplication1.exe' has exited with code 0 (0x0). |
XML в MS SQL Server 2000 и технологиях доступа к данным | SQL Server как Web-сервис | Дальше » |