SQL.RU
 client/server technologies
Rambler's Top100
 Главная | Документация | Статьи | Книги | Форум | Опросы | Каталог | Гостевая | Рассылка | Работа | Поиск | FAQ |
XML в MS SQL Server 2000 и технологиях доступа к данным | XML-шаблоны как разновидность хранимых процедур Дальше »

Шаблоны (templates) объединяют в себе квантово-волновой (SQL / XML) дуализм SQL Server. Козьма Прутков мог бы смело их уподобить хранимым процедурам, которые допускают как SQL-, так и XPath-запросы. Шаблон - это XML-файл, структура которого показана на рис.6.


<?xml version="1.0" encoding="utf-8" ?> 
<Солянка xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:header>
     <sql:param name="Колво"></sql:param>
     <sql:param name="Сумма">1000</sql:param>
  </sql:header>
  <sql:query client-side-xml="0">
    SELECT TOP 1 * FROM Employees FOR XML AUTO
  </sql:query>
  <sql:query client-side-xml="1">
    SELECT c.ContactName, COUNT(o.OrderDate) AS 'Кол-во' 
	FROM Customers c INNER JOIN Orders o ON c.CustomerID = o.CustomerID 
	GROUP BY c.ContactName HAVING COUNT(o.OrderDate) >= @Колво 
	FOR XML NESTED
  </sql:query>
  <sql:xpath-query mapping-schema="..\Schemas\SQLSchema1.xsd">
	Клиент[number(Заказы/Заказ/Стоимость)&gt;$Сумма]
  </sql:xpath-query>
  <sql:xpath-query mapping-schema="..\Schemas\SQLSchema2.xsd">
    Сотрудник
  </sql:xpath-query>
</Солянка>

Рис.6

Он состоит из частей трех основных типов. Каждая часть является опциональной. В <sql:query> перечисляются операторы SQL, в <sql:xpath-query> - запросы XPath, в <sql:header> описываются параметры для запросов (как SQL, так и XPath). Привязка описаний параметров в заголовке к параметрам в запросах осуществляется при помощи атрибута name ("Колво" - @Колво, "Сумма" - $Сумма). В одной секции <sql:query> может находиться несколько SQL-запросов, в отличие от XPath-запросов, каждый из которых должен заключаться в свою секцию <sql:xpath-query>. В данном примере SQL-запросы пришлось разнести по разным секциям, так как первый из них выполняется на сервере, а второй - на клиенте. Атрибут client-side-xml эквивалентен свойству ClientSideXml класса SqlXmlCommand, с которым мы сталкивались в п.6. В <sql:query> могут присутствовать не только select'ы, но и операторы объявления и модификации данных, а также вызовы хранимых процедур, что позволяет помещать в секцию не просто несколько разрозненных операторов, а последовательность, связанную логикой выполнения. Условие - весь select-вывод должен идти в виде XML. Допускаются опции AUTO и EXPLICIT. XPath-запросы выполняются относительно заданной в атрибуте mapping-schema аннотированной схемы. Для каждого XPath-запроса она может быть своя. Отметим, что некоторые (хоть все) из задействованных аннотированных схем могут располагаться непосредственно в файле шаблона, так что предыдущий шаблон можно записать как:


<?xml version="1.0" encoding="utf-8" ?> 
<Солянка xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <xs:chema xmlns:xs="http://www.w3.org/2001/XMLSchema"            	                             
  _    xmlns:ms="urn:schemas-microsoft-com:mapping-schema"
	     id="SQLSchema2" sql:is-mapping-schema="1">
...Схема с рис.5...
  </xs:schema>
 ...<sql:header> и <sql:query>-секции с рис.6...
  <sql:xpath-query mapping-schema="..\Schemas\SQLSchema1.xsd">
	Клиент[number(Заказы/Заказ/Стоимость)&gt;$Сумма]
  </sql:xpath-query>
  <sql:xpath-query mapping-schema="#SQLSchema2">
    Сотрудник
  </sql:xpath-query>
</Солянка>

Рис.7

Таким образом, результат выполнения шаблона может состоять из фрагментов различных схем, соответствующих разным секциям, объединенных корневым элементом. Остается сохранить его в файле формата UTF-8 (Скрипт 11).


static void Execute_TemplateFile_SQLXML()
{
	...
	cmd.CommandText = "..\\Templates\\XMLTemplate1.xml";
	cmd.CommandType = SqlXmlCommandType.TemplateFile;
	SqlXmlParameter prm = cmd.CreateParameter();
	prm.Name = "@Колво"; prm.Value = 20; 
	XmlDocument xml = new XmlDocument();
	xml.Load(cmd.ExecuteStream());
	...
}

Скрипт 11

Вызывающее приложение передает шаблону только один параметр @Колво = 20 (показать клиентов и количество сделанных ими заказов, если оно превышает 20). Для другого запроса будет взято значение параметра по умолчанию из шаблона - <sql:param name="Сумма">1000</sql:param> (показать только тех клиентов, которые сделали хотя бы один заказ на сумму свыше 1000). Если приложение не обеспечивает параметра при вызове шаблона и секция <sql:header> не содержит значение параметра по умолчанию, то для него будет использовано значение по умолчанию, определенное в схеме SQL Server (DEFAULT для поля таблицы или для параметра хранимой процедуры). Если значение по умолчанию в схеме SQL Server также не определено, значение параметра полагается в NULL. Стоит обратить внимание на конвертацию number(Заказы/Заказ/Стоимость) в одном из XPath-запросов в шаблонах рис.6, 7. Дело в том, что несмотря на объявление стоимости как xs:type="xs:float" параметр $Сумма норовит передаваться как nvarchar, что приводит к неверным результатам (напр. '5.00' > '1000'). Еще один, эквивалентный, способ вызова шаблона из SqlXml состоит в использовании свойства CommandStream вместо CommandText. Соответственно должно быть скорректировано свойство CommandType.


...
cmd.CommandStream = new FileStream("..\\Templates\\XMLTemplate1.xml", FileMode.Open, FileAccess.Read);
cmd.CommandType = SqlXmlCommandType.Template;
...

Или даже так:


...
cmd.CommandStream = new MemoryStream();
		StreamWriter sw = new StreamWriter(cmd.CommandStream, System.Text.Encoding.UTF8); 
		sw.Write("<?xml version='1.0' encoding='utf-8' ?> " +
		"<Солянка xmlns:sql='urn:schemas-microsoft-com:xml-sql'>" +
		
...Содержание шаблона с рис.6...
"</Солянка>"); sw.Flush(); cmd.CommandStream.Position = 0; cmd.CommandType = SqlXmlCommandType.Template; ...

В свойстве XslPath класса SqlXmlCommand может задаваться ссылка на XSL-преобразование, которому подвергается сформированный на основе шаблона XML-файл. Преобразование можно также оговорить в корневом элементе шаблона (например, sql:xsl="....xsl">).
Для повышения производительности применяется кэширование шаблонов, что означает, что они не выгружаются из памяти после первого выполнения. Емкость кэша (в штуках) задается в HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\SQLXML3\TemplateCacheSize и по умолчанию равна 31. Чтобы запретить кэширование, необходимо зайти в закладку Advanced свойств виртуальной директории SQL Server (см. п.13) и отметить Disable Caching of template. Аналогично настраивается кэширование аннотированных схем (HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\SQLXML3\SchemaCacheSize).

XML в MS SQL Server 2000 и технологиях доступа к данным | XML-шаблоны как разновидность хранимых процедур Дальше »
Rambler's Top100 Parking.ru Рейтинг@Mail.ru  Administrator: admin@sql.ru 
Last update: 07 окт 2003 
Hosted by uCoz