Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Высокоуровневые методы программирования..pdf
Скачиваний:
8
Добавлен:
15.11.2022
Размер:
10.32 Mб
Скачать

RETURNS @temp_oklad end

SET NOCOUNT OFF Вызов функции:

SELECT @MyOklad = GET_MAX_OKLAD()

PRINT ’На “Телта” = ’ + GET_MAX_OKLAD(’Tелта’)

SELECT COUNTO FROMT_Worker —

^С ф ормулируй-)

WHERE (oklad = GET_MAX_OKLAD()) and

"“"ч

те физический

(zavod LIKE ’ЖБК’)

l

смысл!

4.3. Курсоры

SQL Server может выдать в качестве результата выполнения запроса огром­ ный блок данных. Поэтому мощности клиентских компьютеров и приложений не всегда хватает для комфортной работы с таким объемом информации. Для решения этой проблемы и предназначены курсоры.

Курсор - это механизм обмена данными между сервером и клиентом. Кур­ соры позволяют клиентским приложениям работать не с целым набором дан­ ных, а лишь с его частью, на которую указывает «окно просмотра» курсора или его текущая позиция.

Курсоры позволяют выполнять не только горизонтальную фильтрацию дан­ ных (отсеивание ненужных строк), но и вертикальную (отсеивание столбцов). В результате минимизируется результирующий набор данных, который либо пере­ дается на компьютер клиента, либо остается в памяти сервера, но помечается как объект, владельцем которого является клиентское приложение.

4.3.1. Разновидности курсоров

По типу получения данных курсоры разделяются на обычные и блочные. Блочные курсоры с помощью директивы fetch позволяют извлекать сразу не­ сколько строк из набора данных. Обычные курсоры могут извлекать значения полей только одной строки (текущей позиции курсора).

По типу навигации курсоры классифицируются на последовательные и прокручиваемые. Последовательные курсоры позволяют перемещаться толь­ ко в одном направлении - от начала к концу набора данных. Прокручиваемые курсоры позволяют выполнять навигацию в любом направлении.

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

-статические курсоры - работают по принципу моментального снимка;

-динамические курсоры - изменения видны в выборке, но любые действия с курсором требуют подтверждения;

- последовательные курсоры - отслеживают изменения данных. Наиболее распространенными в практике являются динамические про­

кручиваемые курсоры. Они эффективны в большинстве задач.

4.3.2. Работа с курсором

Принцип работы с курсорами любого типа одинаков. 1. Создание курсора:

DECLARE имя [INSENSITIVE] [SCROLL] CURSOR FOR выборка [FOR действие]

INSENSITIVE - создать копию выбираемых данных во временной табли­ це Tempdb;

Выборка - операция SELECT с перечнем столбцов (недопустим символ *). Действие - READ ONLY или UPDATE [OF столбец[,...n]]

DECLARE @cur_1 Cursor

Set @cur_1 = CURSOR DYNAMIC SCROLL FOR select productjd, kolvo from #tmp1

2. Открытие курсора: OPEN имя

Open @cur_1

3. Выборка из курсора для чтения или изменения строк данных с запоми­ нанием результата в переменных:

FETCH [NEXT или PRIOR или FIRST или LAST ] FROM имя

INTO списокпеременных

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

Prior - при первом обращении ничего, иначе текущая с переходом на предыдущую

Fetch Next From @cur_1

into @var_product_ld, @var_kolvo

4. Закрытие курсора: CLOSE имя

Close @cur_1

5. Освобождение (деактивация) курсора: DEALLOCATE имя

Deallocate @cur_1

End

Else

Begin

Insert into tgod (god) values (year(@date_x))

Select @id_tgod_x=id from Tgod where god=year(@date_x) End

Set @id_tmes_x=Month(@date_x)

Insert into tzarp(zarp,id_tgod,id_tmes,id_trab) values(@sum_x,@id_tgod_x,@id_tmes_x)@id_trab_x) end

Пример 2. Определить, когда (месяц) и какие работники заданного возраста получали заработную плату выше среднего уровня в указан­ ном году

А) Подпрограмма-функция, возвращающая средний уровень заработной платы по организации в указанном году

CREATE FUNCTION is_avg_zp(@year_x integer) RETURNS decimal(10,2)

AS BEGIN

DECLARE @is_avg decima!(10,2) Select @is_avg=avg(t1 .zarp)

from dbo.Tzarp t1 inner join dbo.tgod t2 on t1 .id_tgod=t2.id

where t2.god =@year_x RETURN(@is_avg) END

Б) Процедур:

CREATE PROCEDURE rabjnfo @firstold integer,

@lastold integer, @year_st integer AS

Declare @avg_x decimal(10,2) Set@avg_x=db_lec2.dbo.is_avg_zp(@year_st) SELECT t2.Fam,t4.God,t5.mes,t3.Zarp AS Сумма from dbo.TMrab t1 INNER JOIN

dbo.TRab t2 ON t1 .id = t2.id_TMrab INNER JOIN dbo.TZarp t3 ON t2.id =t3.id_Trab INNER JOIN dbo.TGod t4 ON t3.id_TGod = t4.id INNER JOIN dbo.Tmes t5 ON t3.id_Tmes =t5.id

where t3.Zarp>@avg_x and

datediff(year,t2.data_r,getdate())>=@firstold and datediff(year,t2.data_r,getdate())<=@lastold and t4.God=@year_st

В) Вызов процедуры.

EXECUTE rab_info @firstold = 20, @lastold = 40, @year_st=2001

Пример 3. Определить для каждого работника в указанном году диа­ пазон изменения заработной платы и количество раз выдачи заработной платы. Использовать динамический курсор.

А) Подпрограмма-функция, возвращающая набор данных:

CREATE FUNCTION fn_Find_zp (@year_x integer)

RETURNS @temp1 TABLE(fam varchar(30), Zp_min decimal(10,2), Zp_max decimal(10,2), Zp_cnt integer)

AS BEGIN

DECLARE @reports TABLE(fam varchar(30), Zp_min decimal(10,2),Zp_max decimal(10,2), Zp_cnt integer)

INSERT @reports SELECT t1.fam)min(t2.zarp),max(t2.zarp),count(t2.id)

FROM dbo.trab t1 INNER JOIN Dbo.Tzarp t2 on t1.id=t2.id_trab INNER JOIN dbo.Tgod t3 ON T2.id_tgod=t3.id WHERE t3.god=@year_x GROUP BY t1.fam ORDER BY t1 .fam

INSERT @temp1 SELECT fam,zp_min,zp_max,zp_cnt FROM @reports RETURN

END

/*select * from fn_find_zp(2001)*/

Б) Процедура, использующая набор данных, возвращаемых функцией:

CREATE (ALTER) PROCEDURE dipjnfo @year_st integer,@rec_n integer,@rec_k integer AS

Declare @cur_info cursor, @famx varchar(30), @Zp_minx decimal(10,2), @Zp_ maxx decimal(10,2), @Zp_cntx integer, @rec_temp integer

Set NOCOUNT ON begin

DECLARE @temp3TABLE( fam varchar(30),

Zp_min decimal(10,2), Zp_max decimal(10,2), Zp_cnt integer)

Select fam,zp_min,zp_max,zp_cnt into #temp1 from fn_fmd_zp(@year_st)

- Объявляем курсор локальным, динамическим с прокруткой строк

Set @cur_info=CURSOR LOCAL DYNAMIC SCROLL FOR Select fam,Zp_min,Zp_max,Zp_cnt from #temp1

-Открываем курсор

Open @cur_info set @rec_temp=l

-Считываем первую строку до начала цикла, чтобы @@Fetch_Status=0

-иначе @@Fetch_Status— 2 отсутствуют записи в курсоре

Fetch Next From @cur_info into @famx,@Zp_minx,@Zp_maxx,@Zp_cntx While @@Fetch_Status=0 /*Пока не -1 выход за границы набора*/ Begin

-Запоминаем результат выборки во временной таблице, если запись попадает в диапазон

if (@rec_temp>=@rec_n) and (@rec_temp<=@rec_k) Begin

Insert into @temp3(famIZp_minlZp_max,Zp_cnt) values(@famx,@Zp_minx,@Zp_maxx1@Zp_cntx) end

-Считываем из курсора очередную строку и запоминаем содержимое в переменных

Fetch Next From @cur_info into @famx,@Zp_minx,@Zp_maxx,@Zp_cntx Set @rec_temp=@rec_temp-M

End

close @cur_info /‘ Переводим курсор в неактивное состояние*/

Deallocate @cur_info /‘Освобождаем ресурсы (память), отведенные под курсор*/

Select * from @temp3 End

EXECUTE dipjnfo @year_st=2001 ,@rec_n=2,@rec_k=4