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

Ковалев Язык баз данных SQL

.pdf
Скачиваний:
18
Добавлен:
29.03.2016
Размер:
329.68 Кб
Скачать

11. Курсоры

Курсор (current set of records текущий набор записей) представляет собой объект, позво- ляющий осуществить работу с отдельными строками результирующего запроса.

Использование курсора связано со следующими шагами:

1)declare объявление курсора,

2)open открытие курсора,

3)fetch, update, delete работа с курсором,

4)close закрытие курсора,

5)deallocate освобождение курсора.

11.1Объявление курсора

Оператор объявления курсора применительно к его имени имеет следующий вид:

 

 

 

описание курсо-

ра

 

 

 

 

 

 

 

declare имя_курсора cursor

 

[видимость]

::= [local | global]

[прокрутка]

::= [forward_only | scroll]

[тип]

::= [static | keyset | dynamic | fast_forward]

[блокировка]

::= [read_only | scroll_locks | optimistic]

 

 

[type_warning] for оператор_select

[for update [of имя_столбца ,..]]

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

Параметр прокрутка может принимать одно из значений

1)forward_only последовательный курсор,

2)scroll прокручиваемый в обоих направлениях.

Курсор типа static это статический курсор. Статический курсор делает как бы моментальный снимок данных, задаваемых оператором select, и хранит их в системной базе данных tempdb. Он не чувствует изменений в структуре или в значениях данных таблиц, на которых базируется оператор select. Любые модификации статического курсора отражаются лишь в копии, а не в исходных таблицах. Поэтому он всегда открывается в режиме только для чтения.

Курсор типа keyset это ключевой курсор. Ключевой курсор копирует в базу tempdb только те столбцы, которые уникально идентифицируют каждую строку результирующего запроса по оператору select. Чтобы иметь возможность объявить ключевой курсор, каждая таблица, вхо- дящая в определение оператора select, должна иметь ключ. Ключевые курсоры могут быть как модифицируемыми, так и только для чтения. Они также могут быть прокручиваемыми или по- следовательными. Членство строк в ключевом курсоре фиксируется на момент объявления кур- сора. Даже если строка удаляется, она по-прежнему остается в курсоре, но SQL Server возвра- щает null-значения для всех столбцов. Изменения значений данных, вносимые в исходные таб- лицы, отражаются в курсоре. Однако изменения значений ключей отражаются в курсоре только в том случае, когда они осуществляются в курсоре, а не в исходных таблицах.

Курсор типа dynamic это динамический курсор. Динамический курсор ведет себя так, как ес- ли бы при каждом обращении к строке повторно выполнялся оператор select. Динамические

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

31

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

Курсор типа fast_forward это «пожарный» курсор, т.е. курсор быстрого доступа. Пожарный курсор является специальной оптимизированной формой последовательного курсора для чте- ния.

Параметр блокировки может принимать значения

1)read_only курсор не может вносить никаких изменений в исходные таблицы. Тем не менее, исходные таблицы можно модифицировать с помощью оператора update.

2)scroll_locks обновления могут быть выполнены только курсором. Другие операторы update выполняться не будут.

3)optimistic обновления могут быть выполнены как курсором, так и операторами update.

SQL Server автоматически преобразует тип курсора, если объявленный тип курсора не поддер- живается заданным оператором select. При заданной опции type_warning при таком преобразо- вании SQL Server будет посылать предупреждающие сообщения клиенту.

Фраза for update позволяет явно разрешить обновление курсора, а также явно указать столбцы, допускающие обновление.

11.2 Курсорные переменные

Transact-SQL позволяет объявлять курсорные переменные.

Синтаксис объявления может иметь одну из 2х следующих форм.

declare имя_курсора cursor

Форма 1

описание_курсора

declare @имя_переменной cursor set @имя_переменной = имя_курсора

declare @имя_переменной cursor

Форма 2 set @имя_переменной cursor описание_курсора

Форма 1 полезна для создания переменных, которые могут быть назначены различным курсо- рам. Это может потребоваться для создания обобщенных процедур, предназначенных для рабо- ты с различными результирующими запросами.

Объявление курсора в форме 2 не задает его имени и, следовательно, ссылка на курсор может быть осуществлена только через переменную.

11.3 Открытие курсора

Объявление курсора создает объект курсора, но не создает набор записей, которыми курсор бу- дет манипулировать. Сам набор записей курсора создается при открытии курсора с помощью следующего оператора

open [global] имя_или_переменная_курсора

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

32

Ключевое слово global помогает избежать конфликтов имен. А именно, если локальный и гло- бальный курсоры имеют одинаковые имена, то ссылки на курсор будут по умолчанию отнесены к локальному курсору. Поэтому, как и в других подобных случаях, лучше явно указывать клю- чевое слово global, если работа идет с глобальным курсором.

11.4 Закрытие курсора

После использования курсора его необходимо закрыть. Оператор закрытия close освобождает ресурсы, используемые для обслуживания набора записей курсора, а также освобождает блоки- ровки, наложенные на строки.

Синтаксис оператора закрытия курсора:

close [global] имя_или_переменная_курсора

11.5 Освобождение курсора

Последним оператором в последовательности действий по использованию курсора является его освобождение:

deallocate [global] имя_или_переменная_курсора

Однако оператор deallocate удаляет имя или переменную курсора, на не обязательно сам кур- сор. Сам курсор не удаляется до тех пор, пока все ссылающиеся на него имена или переменные не будут удалены.

Рассмотрим пример:

declare curName cursor

описание_курсора open curName

...

declare @curVariable cursor set @curVariable = curName

...

close curName deallocate curName

После освобождения курсора идентификатор curName больше не ассоциируется с набором за- писей курсора. Но поскольку на набор записей курсора еще ссылается переменная @carVariable, то курсор и его набор записей фактически не освобождаются. Если явно не осво- бодить также и курсорную переменную, то курсор будет существовать вплоть до выхода из процедуры, когда курсорная переменная будет неявно освобождена.

11.6 Оператор fetch

Оператор fetch позволяет выбирать строки курсора и записывать их в переменные:

fetch {first | last | next | prior | absolute n | relative n}

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

33

from имя_или_переменная_курсора into @имя_переменной ,..

Оператор fetch absolute n выбирает строку, отстоящую на n строк от начала, если n > 0, или от конца, если n < 0. Оператор fetch relative n выбирает строку, отстоящую на n строк от текущей вперед или назад при n > 0, n < 0 соответственно. Значением n может быть константа или пере- менная.

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

Глобальная переменная @@fetch_status содержит информацию о выполнении последнего опе- ратора fetch:

@@fetch_status

Описание

0

Оператор fetch выполнен успешно

-1

Оператор fetch выполнен неудачно

-2

Выбираемая строка отсутствует

11.7 Обновление и удаление строк через курсоры

Оператор обновления строки через курсор имеет следующий вид:

update имя_таблицы

set {имя_столбца = новое_значение} ,..

where current of имя_или_переменная_курсора

Это называется позиционным обновлением.

Transact-SQL поддерживает также позиционное удаление:

delete имя_таблицы

where current of имя_или_переменная_курсора

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

34

ПРИЛОЖЕНИЕ

Таблицы

 

 

 

create table

имя_таблицы

 

(

 

 

 

 

{

имя_столбца

тип_данных [ null | not null ]

 

[

default константное_выражение

 

|

identity (начальное_значение, шаг_приращения)

 

]

constraint имя_ограничения

 

[

 

 

{

primary key [ clustered | nonclustered ]

 

 

|

unique

[ clustered | nonclustered ]

 

 

|

foreign key references ссылочная_таблица(имя_столбеца)

 

 

 

 

[ on update [ cascade | no action ] ]

 

 

 

 

[ on delete [ cascade | no action ] ]

 

 

|

check (проверочное_ограничение_для_столбца)

 

 

}

 

 

 

] ,..

 

 

 

} ,..

[ , имя_столбца as выражение_вычисляемого_столбца ] … [ , constraint имя_ограничения

{primary key [ clustered | nonclustered ] ({ имя_столбца [asc | desc] } ,..)

|

unique

[ clustered | nonclustered ] ({ имя_столбца [asc | desc] } ,..)

|

foreign key (имя_столбца ,..) references ссылочная_таблица (имя_столбеца ,..)

 

 

[on update

[ cascade | no action ]]

 

 

[on delete

[ cascade | no action ]]

|

check (проверочное_ограничение_для_строки)

}

 

 

 

] ...

)

Индексы

create [unique] { clustered | nonclustered } index имя_индекса

on имя_таблицы ({имя_столбца [asc | desc ]} ,..)

Вставка строк

insert into имя_таблицы [(имя_столбца ,..)] Форма 1 оператор_select

Форма 2

insert into имя_таблицы [(имя_столбца ,..)] values({ default | null | выражение } ,..)

Форма 3

insert into имя_таблицы default values

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

35

Обновление строк

update имя_таблицы

set {имя_столбца = новое_значение} ,.. [from табличный_источник ,..]

[where условие_поиска]

Удаление строк

delete имя_таблицы

[from табличный_источник ,..] [where условие_поиска]

Базовый оператор select

select [all | distinct] [top целое [percent]]

выбираемый_столбец ,..

[from табличный_источник ,..] [where условие_поиска]

[group by [all] выражение_группировки ,..] [having условие_поиска]

Выбираемый столбец

{[имя_или_псевдоним_таблицы.]*

|

[имя_или_псевдоним_таблицы.]имя_столбца [as псевдоним_столбца]

|

выражение_вычисляемого_столбца [as

псевдоним_столбца]

}

 

 

Табличный источник

 

{

имя_таблицы [as псевдоним_таблицы]

 

|

(оператор_select) as псевдоним_таблицы

|

соединенные_таблицы

 

}

 

 

Соединенные таблицы

 

{

табличный_источник cross join табличный_источник

|

табличный_источник тип_соединения

табличный_источник on условие_поиска

|

(соединенные_таблицы)

 

}

 

 

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

36

Тип соединения

{inner join

|

 

left

[outer] join

 

 

|

 

right

[outer] join

 

 

|

 

full

[outer] join

 

 

}

 

 

 

 

 

 

Фраза where

 

 

 

предикат::=

 

 

 

 

1

{

выражение

{< | <= | = | < > | >= | >}

выражение

2

|

выражение

[not] between выражение1 and выражение2

3

|

выражение

is [not] null

 

4

|

строковое_выражение [not] like шаблон [escape ‘escape_ символ’]

5

|

выражение

[not] in

(выражение ,..)

 

6

|

выражение

[not] in

(подзапрос)

 

7

|

выражение

{< | <= | = | < > | >= | >}

{all | any} (подзапрос)

8

|

exists (подзапрос)

 

 

 

}

 

 

 

 

 

Символы замещения:

1)%

2)_ (подчеркивание).

3){_[символ-символ]_ | _[символ]_}

4){_[^символ-символ]_ | _[^символ

Функции агрегирования

1)count(*)

2){count | sum | avg | min | max} ([all | distinct] выражение_над_столбцами)

Операция union и фраза order by

 

 

 

выражение

select

 

 

 

 

 

 

 

оператор_select::=

{базовый_оператор_select | (выражение_select)} [ union [all]

{базовый_оператор_select | (выражение_select)}

] ...

[ order by {выражение_сортировки [asc | desc]},..

]

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

37

Хранимые процедуры

create procedure имя_процедуры

[ @имя_параметра тип_данных [= значение_по_умолчанию] [output] ] ,..

as

операторы Вызов хранимой процедуры:

 

exec [@имя_переменной = ] имя_процедуры

Форма 1

[

аргумент ,..

Форма 2

|

{@имя_параметра = аргумент} ,..

Форма 3

|

{аргумент ,..}, {@имя_параметра = аргумент} ,..

 

]

 

аргумент ::= {выражение | default | @имя_переменной output}

Скалярные пользовательские функции:

create function имя_функции

(

[ @имя_параметра тип_данных [= значение_по_умолчанию] ] ,..

)

returns тип_данных as

begin

операторы

end

Вызов скалярной пользовательской функции:

имя_функции ([аргумент ,..]) аргумент ::= {выражение | default}

Форма 1 exec @имя_переменной = имя_функции ([аргумент ,..])

Форма 2 exec @имя_переменной = имя_функции {@имя_параметра = аргумент } ,..

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

38

Табличные пользовательские функции

create function имя_функции

(

[ @имя_параметра тип_данных [= значение_по_умолчанию] ] ,..

)

returns table as

return (оператор_select)

create function имя_функции

(

[ @имя_параметра тип_данных [= значение_по_умолчанию] ] ,..

)

returns @имя_таблицы table (определение_таблицы) as

begin

операторы

end

Вызов табличной пользовательской функции:

имя_функции ([аргумент ,..]) аргумент ::= {выражение | default}

Объявление курсора

 

 

 

declare имя_курсора cursor

-

 

 

[видимость]

курсо

 

 

[прокрутка]

 

 

[тип]

описание

ра

 

[блокировка]

 

[type_warning]

 

for оператор_select

 

[for update [of имя_столбца ,..]]

 

 

 

 

 

 

 

::= [local | global]

::= [forward_only | scroll]

::= [static | keyset | dynamic | fast_forward] ::= [read_only | scroll_locks | optimistic]

Курсорные переменные

declare имя_курсора cursor

Форма 1

описание_курсора

declare @имя_переменной cursor set @имя_переменной = имя_курсора

declare @имя_переменной cursor

Форма 2 set @имя_переменной cursor описание_курсора

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

39

Оператор fetch

fetch {first | last | next | prior | absolute n | relative n} from имя_или_переменная_курсора

into @имя_переменной ,..

Спецкурс 3 (2010-2011. 5 курс, 9 сем. ПИЭ), 40 с.

40