Скачиваний:
9
Добавлен:
27.11.2024
Размер:
248.81 Кб
Скачать

СОЗДАНИЕ ХРАНИМЫХ ПРОЦЕДУР И ТРИГГЕРОВ

В MS SQL SERVER

Методические указания к выполнению практической работы по курсу «Современные технологии управления базами данных»

для студентов направления 230400.62 очной, заочной и заочно-сокращенной форм обучения

Цель работы: научиться создавать хранимые процедуры и триггеры в MS SQL Server

ОСНОВНЫЕ ПОНЯТИЯ

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

Хранимые процедуры – предварительно скомпилированная группа команд SQL. Хранимые процедуры имеют имена и обрабатываются как единый рабочий блок. Хранимые процедуры принимают входные параметры и возвращают значения в вызывающую процедуру или команду.

Преимущества хранимых процедур:

-увеличение скорости выполнения. Хранимые процедуры оптимизируются при первой компиляции, это позволяет им запускаться с меньшими издержками по сравнению с командами.

-более быстрый доступ к данным. Хранимые процедуры оптимизированы для наиболее эффективной обработки данных.

-модульное программирование.

-обеспечение целостности базы данных, т.к. клиенты не используют собственных команд.

Усовершенствованный механизм безопасности. Можно предоставить

права выполнения хранимой процедуры пользователю.

Типы хранимых процедур:

-системные (могут только выполняться, предоставляют сведения о базе данных и пользователях)

-пользовательские.

Системные хранимые процедуры.

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

Имена всех системных процедур начинаются с префикса ‘sp_’.

Системные процедуры располагаются в базе данных master.

Пример:

Sp_databasesперечисляет все базы данных, доступные на данном сервере

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

Sp_tables – перечисляет все объекты, к которым можно обратиться с запросом в текущей среде.

Пользовательские хранимые процедуры Все хранимые процедуры создаются в текущей базе данных. Чтобы

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

Синтаксис:

CREATE PROCEDURE <имя процедуры> @имя_параметра тип_данных as

Пример: Создадим процедуру, которая по буквам ms или mr будет выводить значения ‘woman’, ‘man’ соответственно

CREATE PROCEDURE checkGender (@name char(10) as

If (substring (@name, 1, 3)=’ms’) print ‘woman’

Else begin

if (substring (@name, 1, 3)=’mr’) print ‘man’) end

Запуск хранимой процедуры осуществляется с помощью команды

EXECUTE (или EXEC) <имя процедуры> (значения, передаваемые параметрам)

Пример

EXECUTE checkGender (‘ms.Olive’)

Использование локальных переменных внутри хранимой процедуры Пример

CREATE TABLE mytable

(

column1 int, column2 char(10)

)

CREATE PROCEDURE InsertRows @start_value int

AS

DECLARE

@loop_counter int, @start_val int

SET

@start_val = @start_value – 1

SET

@loop_counter = 0

WHILE (@loop_counter < 5)

BEGIN

INSERT INTO mytable VALUES (@start_val + 1, "new row") SET @start_val = @start_val + 1

SET @loop_counter = @loop_counter + 1

END

Выполним эту хранимую процедуру с начальным значением 1

EXECUTE InsertRows 1

В таблице mytable получим 5 записей column1 column2

-----------------------

1new row

2new row

3new row

4new row

5new row

После завершения хранимой процедуры переменные @loop_counter и @start_val уже недоступны.

Использование RETURN

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

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

не выполняются. С помощью RETURN вы можете также возвращать целое значение.

Пример. Создадим процедуру GetUnitPrice, которая проверяет, было ли задано входное значение, и если нет, то выводит сообщение для пользователя и возвращается в вызывающую программу. Для этого определим входной параметр со значением по умолчанию NULL и затем будем проверять это значение в процедуре; если входной параметр имеет значение NULL, это означает, что входное значение не задано.

CREATE PROCEDURE GetUnitPrice @prod_id int = NULL

AS

IF @prod_id IS NULL

BEGIN

PRINT "Please enter a product ID number"

RETURN

END

ELSE

BEGIN

SELECT UnitPrice

FROM

Products

WHERE

ProductID = @prod_id

END

 

Пример. Рассмотрим использование RETURN для возврата значения в вызывающую программу. Возвращаемое значение должно быть целым. Это может быть константа или переменная. Вы должны объявить в вызывающей программе переменную, в которой будет храниться возвращаемое значение для дальнейшего использования в этой программе. Например, следующая процедура возвратит значение 1, если цена единицы продукции для продукта,

указанного во входном параметре, меньше $100; иначе она возвратит значение 99.

CREATE PROCEDURE CheckUnitPrice @prod_id int

AS

IF (SELECT UnitPrice

FROM Products

WHERE ProductID = @prod_id) < 100

RETURN 1

ELSE

RETURN 99

Для вызова этой хранимой процедуры и использования возвращаемого значения объявите в вызывающей программе переменную и приравняйте ее возвращаемому значению хранимой процедуры (указав значение 66 в ProductID для входного параметра):

DECLARE @return_val int

EXECUTE @return_val = CheckUnitPrice 66

IF (@return_val = 1) PRINT "Unit price is less than $100"

Удаление хранимых процедур выполняется с помощью команды

DROP PROCEDURE

2. ТРИГГЕРЫ Триггер – это специальный тип хранимой процедуры, которая

запускается автоматически системой SQL Server при модифицировании какой-либо таблицы одним из трех операторов: UPDATE, INSERT или

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

Существует пять типов триггеров: UPDATE, INSERT, DELETE, INSTEAD OF и AFTER. Как следует из названий, триггер UPDATE

активизируется, когда выполняются изменения (обновления) в какой-либо таблице, триггер INSERT активизируется, когда происходит вставка данных в таблицу и триггер DELETE активизируется, когда из таблицы удаляются данные. Триггер INSTEAD OF выполняется вместо операции вставки,

обновления или удаления. Триггер AFTER активизируется после какой-либо запускающей операции и обеспечивает механизм управления порядком выполнения нескольких триггеров. Операции обновления, вставки и удаления называются событиями модификации данных. Можно создать триггер, который активизируется при возникновении более чем одного события модификации данных. Например, вы можете создать триггер,

который будет активизироваться, когда происходит выполнение оператора

UPDATE или INSERT, и такой триггер мы будем называть триггером

UPDATE/INSERT.

Правила работы с триггерами:

Триггеры запускаются только после завершения оператора, который вызвал их активизацию. Например, UPDATE-триггер не будет активизироваться, пока не будет выполнен оператор UPDATE.

Если какой-либо оператор пытается выполнить операцию, которая нарушает какое-либо ограничение по таблице или является причиной какой-

то другой ошибки, то связанный с ним триггер не будет активизирован.

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

Триггер активизируется только один раз для одного оператора, даже если этот оператор влияет на несколько строк данных.

Создание триггеров синтаксис:

CREATE TRIGGER имя_триггера

ON {таблица | представление}

[WITH ENCRYPTION]

{FOR | AFTER | INSTEAD OF} {[DELETE] [,] [INSERT] [,] [UPDATE]}

[WITH APPEND]

[NOT FOR REPLICATION]

AS

оператор_sql [...n]

При создании триггера вы имеете доступ к двум временным таблицам с именами deleted и inserted. Их называют таблицами, но они отличаются от реальных таблиц баз данных. Они хранятся в памяти, а не на диске.

Эти две таблицы имеют одинаковую структуру с таблицей (одинаковые колонки и типы данных), по которой определяется данный триггер. Таблица deleted содержит копии строк, на которые повлиял оператор DELETE или

UPDATE. Строки, удаляемые из таблицы данного триггера, перемещаются в таблицу deleted. После этого к данным таблицы deleted можно осуществлять доступ из данного триггера. Таблица inserted содержит копии строк,

добавленных к таблице данного триггера при выполнении оператора INSERT

или UPDATE. Эти строки добавляются одновременно в таблицу триггера и в таблицу inserted. Поскольку оператор UPDATE обрабатывается как DELETE,

после которого следует INSERT, то при использовании оператора UPDATE

старые значения строк копируются в таблицу deleted, а новые значения строк

– в таблицу триггера и в таблицу inserted.

Пример. Создадим простую таблицу с определенным по ней триггером, который печатает определенный текст при каждой модификации.

Программа T-SQL для создания этой таблицы имеет следующий вид:

USE MyDB

GO

CREATE TABLE Bicycle_Inventory

(

 

 

make_name

char(10)

NOT NULL,

make_id

tinyint

NOT NULL,

model_name

char(12)

NOT NULL,

model_id

tinyint

NOT NULL,

in_stock

tinyint

NOT NULL,

on_order

tinyint

NULL,

)

 

 

CREATE TRIGGER Print_Update

ON Bicycle_Inventory

FOR UPDATE

AS

PRINT "The Bicycle_Inventory table was updated"

Чтобы проверить триггер, выполним вставку строки в эту таблицу и

затем модифицируем ее:

INSERT INTO Bicycle_Inventory VALUES ("Trek",1,"5500",5,1,0)

GO

UPDATE Bicycle_Inventory

SET

make_id = 2

WHERE

model_name = "5500"

GO

Будет возвращено сообщение "The Bicycle_Inventory table was updated",

так как в результате выполнения оператора UPDATE был запущен триггер. В

данном примере мы задали в нашем триггере вывод сообщения, чтобы можно было увидеть работу этого триггера. Но обычно не требуется, чтобы триггер возвращал выходные данные. Однако в определенных обстоятельствах это может оказаться полезным. Например, предположим, что вы создаете триггер типа UPDATE, который выполняет свои операторы, только когда в указанную колонку заносится определенное значение, но эта модификация происходит неверно. Если добавить в триггер оператор PRINT, который выводит значение этой колонки до выполнения других операторов триггера,

это, видимо, поможет определить, где лежит источник проблемы – в логике самого триггера или в модифицируемых данных.

Пример. Создадим триггер типа INSERT (триггер, который активизируется при выполнении оператора INSERT) по таблице sales. Этот триггер при вставке строки в таблицу sales будет модифицировать колонку ytd_sales в таблице titles добавляя в нее значение, которое было помещено в колонку qty таблицы sales. Этот триггер запрашивает таблицу inserted, чтобы получить значение qty, которое было помещено в таблицу sales. Мы включим в этот запрос оператор SELECT *, с помощью которого увидим, что содержит таблица inserted.