Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

699

.pdf
Скачиваний:
4
Добавлен:
15.11.2022
Размер:
3.63 Mб
Скачать

дой строкой второй таблицы, давая тем самым в результате все возможные сочетания строк двух таблиц.

SELECT * FROM

Person CROSS JOIN City

или

SELECT * FROM

Person, City

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Андрей

1

2

Санкт-

 

 

 

Петербург

Андрей

1

3

Казань

Леонид

2

1

Москва

Леонид

2

2

Санкт-

 

 

 

Петербург

Леонид

2

3

Казань

Сергей

1

1

Москва

Сергей

1

2

Санкт-

 

 

 

Петербург

Сергей

1

3

Казань

Григорий

4

1

Москва

Григорий

4

2

Санкт-

 

 

 

Петербург

Григорий

4

3

Казань

Если в предложении WHERE добавить условие соединения (предикат p), т.е. ограничения на сочетания кортежей, то результат будет эквивалентен операции INNER JOIN с таким же условием:

SELECT * FROM

Person, City

181

WHERE

Person.CityId = City.Id

Таким образом, t1 CROSS JOIN t2 WHERE p и t1 INNER JOIN t2 ON p синтаксически являются альтернативными формами записи одной и той же логической операции внутреннего соединения по предикату p. Синтаксис CROSS JOIN + WHERE для операции соединения называют устаревшим, его не рекомендует стандарт SQL ANSI [20].

2.23. Использование XML в запросе в SQL-Server

Корпорация Microsoft усовершенствовала поддержку в SQL Server данных, описываемых на расширяемом языке разметки (Extensible Markup Language, XML), и программ-

ного кода из общеязыковой среды исполнения (Common Language Runtime, CLR) внутри БД.

Работа с XML

XML – это легко читаемый язык иерархической текстовой разметки, который обычно применяется для обмена данными в системах и между системами.

Язык XML применяется в операциях, связанных с БД:

Извлечение реляционных данных в виде документа XML. Вместо получения таблицы данные записываются в документ XML.

Передача данных в виде XML в БД. Вместо передачи

вБД скалярных значений с помощью выполнения множественных инструкций языка манипулирования данными (DML) или многократного выполнения хранимой процедуры можно передать в БД документ или фрагмент XML.

Хранение или запрос действительного документа или фрагмента XML в БД.

Перед тем как приступить к работе с XML, нужно определиться, зачем нужны данные в таком формате. Причиной, по которой выбирается такой способ предоставления

182

данных, может быть то, что данные в таком формате лучше поддаются описанию как иерархии. Как правило, табличные данные сложно представить в виде иерархии. Например, чтобы вывести данные о заказах клиента (customerId=1,2), нужно использовать две таблицы. Можно последовательно составить запрос к таблице Customer и SalesOrderHeader либо выполнить запрос, соединив эти таблицы. Применение операторов Left outer join позволяет включить клиентов без заказов. Оператор order by позволяет последовательно вывести все заказы.

Такие данные трудно обозримы и создадут путаницу в клиентском приложении. Оба варианта создают большой объем работы в клиентском приложении. Решение с XML предпочтительнее, так как извлекает данные в виде иерархии (клиенты, имеющие заказы).

SELECT c.CustomerID AS '@id',c.CompanyName as'@name',

(select p.OrderDate as '@date', p.OrderID as '@Num' from Orders

p

where p.CustomerID=c.CustomerID for XML path('order')) as

'orders'

FROM Customers c

where c.CustomerID in ('a1','a2')

for XML path('customer'),root('customers')

Результат выполнения запроса:

<customers>

<customer id="a1 " name="Vesta"> <orders><order date="2014-09-

03T00:00:00" Num="1"/><order date="2014-09-02T00:00:00" Num="7"/></orders>

183

</customer>

<customer id="a2 " name="Luna"> <orders><order date="2014-09-

03T00:00:00" Num="11"/></orders> </customer>

</customers>

Если использовать этот запрос из приложения среды. NET и извлечь данные XML в память, то можно легко обрабатывать в цикле клиентов и соответствующие заказы.

FOR XML <режим>

В предыдущем примере для форматирования результата на языке XML в конец инструкции SELECT вставлено дополнительное предложение FOR XML. В языке SQL Server 2008 существуют четыре варианта, применяемые в предложении FOR XML: RAW, AUTO, EXPLICIT и PATH.

FOR XML RAW – простейшая реализация предложе-

ния FOR XML:

select c.CustomerId AS '@id', c.CompanyName as'@name'

from Customers c

where c.CustomerId in ('a1','a2') for XML raw;

Как правило, такой запрос возвращает почти каждую строку как элемент XML, а каждый столбец – как элемент

XML:

(<row Column1="…" Column1="…" />) <row _x0040_id="a1 "

_x0040_name="Vesta" />

<row _x0040_id="a2 " _x0040_name="Luna" />

FOR XML AUTO. Режим AUTO отличается от RAW

тем, что поддерживает иерархии. Однако иерархии должны быть простыми, так как режим AUTO не поддерживает разветвления. Поддерживается иерархия:

184

Customer;

Order;

Order Row.

Не поддерживается следующая иерархия из-за наличия разветвления:

Customer;

Order;

Order Row;

Contacts.

В этом режиме таблица, включенная в запрос, получает собственный элемент иерархии, а имя элемента наследуется от псевдонима таблицы, используемого в запросе. Иерархия создается исходя из порядка столбцов, возвращенных запросом, а не из порядка столбцов в таблицах.

select cust.CustomerID AS '@id', cust.CompanyName

as'@name',ord.OrderID,ord.OrderDate from dbo.Orders as ord right outer

join

dbo.Customers as cust on cust.CustomerID=ord.CustomerID

where cust.CustomerID in ('a1','a2') order by ord.CustomerID for XML auto,

root('Customers');

Результат XML:

<Customers>

<cust _x0040_id="a1 " _x0040_name="Vesta">

<ord OrderID="1" OrderDate="2014-09- 03T00:00:00" />

<ord OrderID="7" OrderDate="2014-09- 02T00:00:00" />

</cust>

<cust _x0040_id="a2 " _x0040_name="Luna">

185

<ord OrderID="11" OrderDate="2014- 09-03T00:00:00" />

</cust>

</Customers>

FOR XML EXPLICIT. С помощью этого предложения можно вернуть результирующий набор. Для получения желаемого результата результирующий набор можно отсортировать. Результирующий набор должен содержать два столбца с именами: Tag и Parent. В столбец Tag вставляется целочисленный идентификатор для каждого элемента XML, который нужно вернуть, а в столбце Parent задается идентификатор из столбца Tag элемента XML, который является родительским для данного элемента. Если у элемента нет предка, в столбце Parent задается NULL. Остальные столбцы в результирующем наборе применяются для определения как имен, так и значений элементов и атрибутов, которые следует вернуть.

select 1 as tag

,null as Parent

,null as "Customers!1!!element"

,null as "Customer!2!Id"

,null as "Customer!2!Custname"

,null as "Order!3!Num"

,null as "Order!3!OrderDate"

,null as "Order!3!Quantity" union all

select 2 as tag

,1 as Parent

,null as "Customers!1!!element"

,c.CustomerID as "Customer!2!Id"

,c.CompanyName as "Customer!2!Custname"

,null as "Order!3!Num"

,null as "Order!3!OrderDate"

,null as "Order!3!Quantity"

from dbo.Customers as c

186

where c.CustomerID in ('a1','a2') union all

select 3 as tag

,2 as Parent

,null as "Customers!1!!element"

,p.CustomerID "Customer!2!Id"

,null as "Customer!2!Custname"

,p.OrderID as "Order!3!Num"

,p.OrderDate as "Order!3!OrderDate"

,p.OrderQuantity as "Order!3!Quantity"

from dbo.Orders as p

where p.CustomerID in ('a1','a2') order by "Customer!2!Id", tag

for XML Explicit;

Результат XML:

<Customers>

<Customer Id="a1 " Custname="Vesta"> <Order Num="1" OrderDate="2014-09-

03T00:00:00" Quantity="233" />

<Order Num="7" OrderDate="2014-09- 02T00:00:00" Quantity="233" />

</Customer>

<Customer Id="a2 " Custname="Luna"> <Order Num="11" OrderDate="2014-09-

03T00:00:00" Quantity="444" /> </Customer>

</Customers>

FOR XML Path. Это наилучший выбор для большинства решений. Режим Path позволяет интерпретировать имена заданных столбцов с помощью выражения XPath.

Select c.CustomerID AS '@id', c.CompanyName as'@name',

c.Phone as "additionalInfo/text()"

from dbo.Customers c

where c.CustomerID in ('a1','a2')

187

for XML path('customer'),root('customers')

Результат XML

<customers>

<customer id="a1 " name="Vesta"> <additionalInfo>>(212) 121-

9686</additionalInfo>

</customer>

<customer id="a2 " name="Luna"> <additionalInfo>(212) 121-

2122</additionalInfo>

</customer>

</customers>

Уданного режима гораздо больше возможностей, чем

урежимов RAW, AUTO, поскольку он позволяет добавлять в результат как атрибуты, так и подэлементы (вложенные элементы), а также заключать в него другие разновидности структур XML. Кроме того, его проще использовать, чем

PATH и EXPLICIT.

Вложение запросов FOR XML

Для создания иерархии все запросы с предложением FOR XML <режим> можно вкладывать друг в друга. Это означает, что для создания законченного документа XML можно поместить один запрос FOR XML в другой запрос

FOR XML.

Рассмотрим следующий запрос и результат:

Select c.CustomerID AS '@id',c.CompanyName as'@name',c.Phone as "additionalInfo/text()",

(select p.OrderDate as '@date', p.OrderID '@Num', p.OrderQuantity as '@Quantity',

(select t.ProductName as "@Tovar", t.Price as "@Price"

from dbo.Product t

188

where t.ProductId=p.ProductId

 

 

for XML path('orderdetail'),type)

 

from dbo.Orders p

 

 

where p.CustomerID=c.CustomerID

as

for

XML

path('order'),type)

'orders'

 

 

 

 

from dbo.Customers c

 

 

where c.CustomerID in ('a1','a2')

 

for XML path('customer');

 

 

Результат XML:

 

 

 

<customer id="a1 " name="Vesta">

 

 

<additionalInfo>1217686</additionalInfo>

 

 

<orders>

 

 

 

 

<order

date="2014-09-03T00:00:00"

Num="1"

Quantity="233">

 

 

 

 

<orderdetail Tovar="Журнал" Price="200.0000" />

 

</order>

 

 

 

 

<order

date="2014-09-02T00:00:00"

Num="7"

Quantity="233">

 

 

 

 

<orderdetail Tovar="Журнал" Price="200.0000" />

 

</order>

 

 

 

 

</orders>

 

 

 

 

</customer>

 

 

 

 

<customer id="a2 " name="Luna">

 

 

<additionalInfo>(212) 121-2122</additionalInfo>

 

<orders>

 

 

 

 

<order

date="2014-09-03T00:00:00"

Num="11"

Quantity="444">

 

 

 

 

<orderdetail Tovar="Журнал" Price="200.0000" /> </order>

</orders>

</customer>

189

Применение типа данных XML

В SQL Server 2008 включен тип данных XML, который может использоваться для хранения фрагментов и документов XML. На внутреннем уровне тип данных XML хранится с помощью типа данных varbinary(max), т.е. XML сохраняется не как текстовая строка, а как двоичное представление документа или фрагмента XML.

Тип данных XML может быть типизированным и нетипизированным. Типизированный означает, что типу для проверки его содержимого присваивается коллекция схем

XML.

2.24. Вставка новой записи

Синтаксис оператора INSERT похож на синтаксис оператора SELECT. Его базовая форма имеет следующий вид:

INSERT [INTO] табли-

ца_или_представление [(список_столбцов)] VALUES (список_значений)

Каждый оператор INSERT может модифицировать только одну таблицу или представление. При использовании оператора INSERT для модификации представления следует учитывать следующие ограничения:

представление не должно содержать функций агрегирования, таких как COUNT или AVG;

представление не должно содержать операторов

TOP, GROUP BY, UNION или DISTINCT;

представление не должно содержать вычисляемых столбцов;

представление должно ссылаться на таблицу во фра-

зе FROM;

оператор INSERT модифицирует столбцы только из одной таблицы.

190

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]