
- •Лабораторная работа № 1.
- •Методические рекомендации по выполнению работы
- •Задания на лабораторную работу
- •Оформление отчета
- •Контрольные вопросы
- •Лабораторная работа № 2. Создания хранимых процедур и функций с использованием средства субд sql Server и языковых конструкций Transact-sql.
- •Методические рекомендации по выполнению работы
- •Задания на лабораторную работу
- •Оформление отчета
- •Лабораторная работа № 3. Использование языка манипулирования данными Transact-sql для создания курсоров
- •Методические рекомендации по выполнению работы
- •Задания на лабораторную работу
- •Оформление отчета
- •Лабораторная работа № 4 Параллельная обработка транзакций
- •Методические рекомендации по выполнению работы
- •Пример выполнения лабораторной работы
- •Задания для самостоятельного выполнения.
- •Оформление отчета
- •Лабораторная работа № 5 Обработка данных многомерной структуры
- •Список рекомендуемой литературы
Методические рекомендации по выполнению работы
(1)
Создание и модификация курсора
Для реализации курсора средствами MS SQL Server воспользуемся хранимой процедурой для создания непосредственно курсора и демонстрации передачи множества данных клиенту.
Выберите в дереве Проводника пункт Stored Procedures и, активизируя всплывающее меню, дайте команду New Stored Procedure. В появившемся окне Stored Procedure Properties в рабочую область выводится шаблон текста процедуры:
DECLARE имя курсора CURSOR
FOR
SELECT поля
FROM таблицы
WHERE условия
и т.д.
OPEN имя курсора
FETCH FROM имя курсора INTO переменные, в которых фиксируются значения возвращаемые конструкцией SELECT
WHILE условие окончания цикла
BEGIN
/* Считывание очередной строки из курсора */
FETCH FROM имя курсора INTO переменные, в которых фиксируются значения возвращаемые конструкцией SELECT
END
CLOSE имя курсора
DEALLOCATE имя курсора
Параметры, определяющие поведение триггеров
AFTER. Триггер выполняется после успешного выполнения вызвавших его команд. Если же команды по какой-либо причине не могут быть успешно завершены, триггер не выполняется. Можно определить несколько AFTER-триггеров для каждой операции (INSERT, UPDATE, DELETE). Если для таблицы предусмотрено выполнение нескольких AFTER-триггеров, то с помощью системной хранимой процедуры sp_settriggerorder можно указать, какой из них будет выполняться первым, а какой последним. По умолчанию в SQL Server все триггеры являются AFTER-триггерами.
INSTEAD OF. Триггер вызывается вместо выполнения команд. В отличие от AFTER-триггера INSTEAD OF – триггер может быть определен как для таблицы, так и для представления (VIEW). Для каждой операции INSERT, UPDATE, DELETE можно определить только один INSTEAD OF-триггер.
(2)
(a)
Пример хранимой процедуры Proc_Stores реализующей работу курсора сервера.
Создать курсор, который должен возвращать технические характеристики и наименование изделия, которое поставляет заказчик (имя заказчика) в количестве более (указать количество) единиц, а также суммировать полученный результат (суммировать по полю “количество” таблица ПОСТАВКА)
/* Шаг 0. Объявление процедуры */
CREATE procedure proc_stores
as
/* Шаг 1. Объявление некоторых рабочих переменных */
declare @nOrderCount int,
@nStorCount int,
@sKol_vo int,
@sIzdelie char(50),
@sTeh_harakteristika char(50),
@sZakazchik char(50)
/* Шаг 2. Отключение результирующего счетчика. Отключаем необязательное
сообщение "O row affected messages", выдаваемое на экран клиента */
set NoCount ON
/* Шаг 3. Создает ресурсные структуры,
которые требуются для управления курсором. */
declare cur_stores cursor
for
SELECT Наименование, Тех_характеристики, Заказчик, Количество
FROM (ИЗДЕЛИЕ inner join ПОСТАВКА
on ИЗДЕЛИЕ.Код_модели = ПОСТАВКА.Код_модели)
inner join ЗАКАЗ on ПОСТАВКА.Номер_заказ = ЗАКАЗ.Номер_заказ
WHERE Количество > 10
/* Шаг 4. Открытие курсора.
Создается первоначальный результирующий
набор и готовятся данные для передачи. */
open cur_stores
/* Шаг 5. Первое считывание.
Считываются данные из курсора в переменные для обработки и оценки. */
fetch cur_stores
into @sIzdelie, @sTeh_harakteristika, @sZakazchik, @sKol_vo
/* Шаг 6. Инициализация счетчиков */
/* Здесь SELECT выполняет роль оператора присваивания */
select @nStorCount = 0
/* Шаг 7. Цикл считывания.
Обрабатываются данные, пока значение переменной @@fetch_status = 0
(это значит, что строка была считана из курсора). */
while @@fetch_status = 0
begin
/* Шаг 8. Увеличение счетчика. */
select @nStorCount = @nStorCount + 1
/* Шаг 9. Определение общего количества изделий заказов превышающих заданный параметр (>10) */
select @nOrderCount = @nOrderCount + @sKol_vo
/* Шаг 10. Возвращение результата клиенту */
select ‘Изделие’ = @sIzdelie,
‘Техническая характеристика’ = @sTeh_harakteristika,
‘Заказчик’ = @sZakazchik,
‘Количество изделий’ = @sKol_vo
/* Шаг 11. Продолжение считывания.
Если больше не найдено ни одной строки, значение переменной
@@fetch_status будет установлено не равным нулю и цикл завершается */
fetch cur_stores
into @sIzdelie, @sTeh_harakteristika, @sZakazchik, @sKol_vo
end
/* Шаг 12. Закрытие и освобождения курсора.
Следует отметить, что для хранимой процедуры это необязательно,
так как курсор прекращает свое существование сразу же после
завершения хранимой процедуры. Однако лучше это проделывать. */
close cur_stores
deallocate cur_stores
/* Шаг 13. Оформление общего результата. */
select 'Количество изделий' = @nStorCount
select 'Суммарное количество изделий' = @nOrderCount
/* Шаг 14. Повторное включение результирующего счетчика */
set NoCount ON
/* Шаг 15. Завершение процедуры
0 показывает, что процедура выполнилась успешно, от –1 до –99 показывает причины неудачного завершения. */
return 0
Вызов процедуры Proc_Stores
Вызов курсора осуществить из Query Analyzer с проверкой наличия хранимой процедуры в базе данных.
Для процедуры Proc_Stores это можно выполнить с помощью фрагмента программы следующего вида
USE <имя БД> /* Связь с базой данных */
IF (SELECT object_id('proc_stores')) IS NOT NULL
BEGIN
PRINT 'Процедура существует, ожидайте результат...'
PRINT ''
EXECUTE proc_stores /* Выполнение курсора */
END
ELSE
PRINT 'Процедура в базе данных отсутствует'
Здесь функция select(object_id('proc_stores')) возвращает номер объекта в базе данных, если объект существует. Если объект 'proc_stores' в базе данных не существует, то select(object_id('proc_stores')) вернет значение NULL.
Для идентификации базы данных можно использовать либо окно DB на панели инструментов Query Analyzer, либо команду USE <имя базы> данных как показано в примере.
(b)
Пример (тот же) реализующий работу курсора клиента.
Для этого необходимо воспользоваться синтаксическими конструкциями шагов 1 – 14, и активизировать их в окне Query Analyzer. При этом вызов процедуры, не используется.
(c)
Пример (тот же) реализующий работу смешанного курсора.
Для создания курсора как выходного параметра процедуры, необходимо часть синтаксических конструкций курсора, в частность запрос и открытие курсора, сохранить как хранимую процедуру на стороне сервера, а считывание очередной строки и формирования результата активизировать на стороне клиента (приложения).
Общий синтаксис смешанного курсора приведен ниже.
Хранимая процедура на сервере.
CREATE PROC my_proc @cur CURSOR VARYING OUTPUT
AS
SET @cur = CURSOR FORWARD_ONLY STATIC
FOR
SELECT Название FROM Товар
OPEN @cur
Вызов процедуры в приложении.
DECLARE @my_cur CURSOR
DECLARE @n varchar(20)
EXEC my_proc @cur=@my_cur OUTPUT
FETCH NEXT FROM @my_cur INTO @n
SELECT @n
WHILE (@@FETCH_STATUS=0)
BEGIN
FETCH NEXT FROM @my_cur INTO @n
SELECT @n
END
CLOSE @my_cur
DEALLOCATE @my_cur
(d)
Пример реализующий работу курсора для последовательной обработки строк
Воспользовавшись формулировкой 1-го триггера лаб. раб. № 1 реализовать возможность построчной обработки данных удовлетворяющих требованиям при удалении одновременно нескольких строк.
create trigger [dbo].[del_kur] on [dbo].[Поставка]
INSTEAD OF delete
as
declare cur_1 cursor
for select * from deleted
declare @a int, @b int, @c int, @aa char(50)
OPEN cur_1
FETCH cur_1 INTO @a, @b, @c
WHILE @@fetch_status = 0
BEGIN
FETCH cur_1 INTO @a, @b, @c
select @aa=Наименование from Изделие where Код_модели=@a
IF @aa='Эл. двигатель' OR @aa='Телефон многоканальный'
insert into Поставка values (@a, @b, @c)
ELSE
delete from Поставка where Код_модели=@a and
Номер_заказа=@b and
Количество=@c
END
CLOSE cur_1
DEALLOCATE cur_1
Для удаления одновременно несколько строк можно сформулировать запрос типа
Delete from Поставка where Количество < 10
(3)