
- •Содержание
- •Введение
- •1Лабораторная работа № 1 Создание концептуальной модели предметной области
- •1.5Критерии результативности выполнения лабораторной работы
- •Контрольные вопросы
- •2Лабораторная работа № 2 Создание и заполнение реляционной базы данных с помощью языка sql
- •2.1Цель лабораторной работы
- •2.2Задачи лабораторной работы
- •2.3Задание
- •2.4Методика выполнения задания
- •Этап 1. Создание структуры реляционной базы данных и ее модификация
- •Этап 2. Выполнение операций вставки, обновления и удаления данных
- •Этап 3. Выполнение операций выборки данных из одной таблицы
- •2.5Критерии результативности выполнения лабораторной работы
- •Контрольные вопросы
- •3.4Методика выполнения задания
- •Этап 1. Сортировка и встроенные функции
- •Этап 2. Вложенные запросы и операция соединения
- •Этап 3. Создание и обновление представлений
- •3.5Критерии результативности выполнения лабораторной работы
- •Контрольные вопросы
- •4Лабораторная работа № 4 Разработка триггеров и хранимых процедур
- •4.5Курсоры
- •4.6Хранимые процедуры
- •4.7Триггеры
- •4.8Методика выполнения задания
- •4.9Требования к оформлению и содержанию отчета
- •4.10 Критерии результативности выполнения лабораторной работы
- •Контрольные вопросы
- •Список литературы
- •Приложение 1 Варианты заданий для лабораторной работы № 1
- •1. Страховая компания
- •2. Гостиница
- •3. Ломбард
- •4. Реализация готовой продукции
- •5. Ведение заказов
- •6. Бюро по трудоустройству
- •7. Нотариальная контора
- •8. Химчистка
- •9. Курсы повышения квалификации
- •10. Сдача в аренду торговых площадей
- •11. Распределение учебной нагрузки
- •12. Распределение дополнительных обязанностей
- •13. Техническое обслуживание станков
- •14. Туристическая фирма
- •15. Грузовые перевозки
- •Приложение 2 Построение концептуальной модели предметной области в пакете AllFusion eRwin Data Modeler Введение
- •5Описание интерфейса
- •6Создание логической модели данных
- •6.1Сущности и атрибуты
- •6.2Связи
- •6.3Ключи
- •1. Табельный номер,
- •7Создание физической модели данных
- •7.1Выбор сервера
- •7.2Таблицы и колонки
- •Приложение 3. Примеры кода на языке sql
- •Операторы ddl (Data Definition Language)
- •Определение первичных и альтернативных ключей с помощью оператора alter
- •Выборка данных – select
- •Внешние соединения
- •Представления
4.5Курсоры
В листингах будут использоваться курсоры.
Курсор – это указатель на набор записей. Обычно курсоры определяются с помощью операторов SELECT. Например, оператор в листинге 3 определяет курсор под названием TransCursor, действующий на наборе строк, указанном в операторе SELECT. Когда прикладная программа открывает курсор и считывает первую строку, о курсоре говорят, что он «указывает на первую строку».
Листинг 3
DECLARE TransCursor CURSOR
FOR SELECT *
FROM TRANS
WHERE SalesPrice > 10000;
4.6Хранимые процедуры
Хранимые процедуры используются для многих целей. Хотя администраторы баз данных используют их для выполнения рутинных задач администрирования, главной областью их применения являются все же приложения баз данных. Эти процедуры могут вызываться из прикладных программ, написанных на таких языках, как Java, C#, C++ или VB.Net, а также из веб-сценариев, написанных на VBScript или JavaScript. Кроме того, эти процедуры можно вызывать в интерактивном режиме из командной оболочки СУБД – например, SQL*Plus в Oracle или Query Analyzer в SQL Server. Наконец, хранимые процедуры как Oracle, так и SQL Server могут вызываться из среды Microsoft Visual Studio.NET.
Как и с другими структурами базы данных, вы можете записать текст процедуры в файл и выполнить ее в среде Microsoft SQL Server Management Studio Express. Есть только одна особенность, которую необходимо знать. В первый раз, когда вы записываете процедуру в текстовый файл, начните ее ключевыми словами CREATE PROCEDURE. Потом, если вы захотите изменить процедуру, поменяйте эти слова на ALTER PROCEDURE, противном случае при попытке запуска измененной процедуры вы получите общение об ошибке, гласящее, что такая процедура уже существует.
Внимание! Помните, что вы не сможете сохранить процедуру в базе данных, пока не исправите все синтаксические ошибки.
4.6.1 Хранимая процедура Customer_Insert. В листинге 4 изображена хранимая процедура, которая сохраняет в базе данных информацию о новом клиенте и связывает этого клиента со всеми художниками заданной национальности. Процедура имеет четыре входных параметра: @NewName, @NewAreaCode, @NewPhone и @Nationality. Как вы можете видеть, параметры и переменные в TRANSACT-SQL предваряются символом @. Первые три параметра – это данные нового клиента, а четвертый параметр представляет собой национальность художников, которыми интересуется новый клиент.
Листинг 4. Хранимая процедура Customer_Insert
CREATE PROCEDURE dbo.Customer_Insert
@NewName char(25),
@NewAreaCode char(3),
@NewPhone char(8),
@Nationality char(30)
AS
DECLARE @Count as smallint
DECLARE @Aid as int
DECLARE @Cid as int
/* Проверяем, нет ли данного клиента в базе */
SELECT @Count=Count(*)
FROM dbo.CUSTOMER
WHERE [Name] = @NewName AND AreaCode = @NewAreaCode AND
PhoneNumber = @NewPhone;
IF @Count > 0
BEGIN
PRINT 'Клиент уже есть в базе данных - никаких действий не предпринято' RETURN
END
/* Добавляем данные о новом клиенте */
INSERT INTO dbo.CUSTOMER ([Name], AreaCode, PhoneNumber)
VALUES (@NewName, @NewAreaCode, @NewPhone);
/* Получаем новое значение суррогатного ключа */
SELECT @Cid=CustomerID
FROM dbo.CUSTOMER
WHERE [Name] = @NewName AND AreaCode = @NewAreaCode AND
PhoneNumber = @NewPhone;
/* Создаем запись в таблице пересечения для каждого художника */
DECLARE Artist_Cursor CURSOR FOR
SELECT ArtistID
FROM dbo.ARTIST
WHERE Nationality=@Nationality;
/* Обрабатываем каждого художника выбранной национальности */
OPEN Artist_Cursor
FETCH NEXT FROM Artist_Cursor INTO @Aid
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO dbo.[CUSTOMER_ARTIST_INT](ArtistID, CustomerID)
VALUES (@Aid, @Cid)
FETCH NEXT FROM Artist_Cursor INTO @Aid
END
CLOSE Artist_Cursor
DEALLOCATE Artist_Cursor
Первая задача, которую выполняет данная хранимая процедура, – проверить, нет ли записи об этом клиенте в базе данных. Если count в первом операторе SELECT оказывается больше 0, это значит, что строка для данного клиента уже существует. Тогда никаких действий не предпринимается, хранимая процедура выводит сообщение об ошибке и завершает свою работу. Это сообщение об ошибке, между прочим, будет видно в Query Analyzer или в Management Sdudio Express, но в общем случае не будет видимым для прикладных программ, вызывающих данную процедуру. Передать сообщение об ошибке пользователю через прикладную программу можно с помощью параметра или каким-нибудь другим способом.
Далее процедура вставляет новые данные в таблицу dbo.CUSTOMER и считывает новое значение CustomerID в переменную @Cid.
Чтобы создать соответствующие строки в таблице пересечения, с помощью SQL-оператора открывают курсор, возвращающий все строки из таблицы ARTIST, в которых значение столбца Nationality равно значению параметра @Nationality. Курсор обрабатывается в цикле LOOP, в процессе чего в таблицу пересечения CUSTOMER_ARTIST_INT вставляются новые строки. Оператор FETCH передвигает курсор на следующую строку.
На рис. 4.3 показано, как с помощью этой хранимой процедуры, вызываемой из Management Sdudio Express, добавить в базу данных нового клиента, интересующегося художниками из США. В таблицу CUSTOMER был добавлен покупатель Michael Bench.
exec Customer_Insert @NewName='Michael Bench', @NewAreaCode='203',
@NewPhone='555-3014', @Nationality='US';
Рис. 4.3. Вызов процедуры Customer_Insert
Рис. 4.4. Повторный вызов процедуры Customer_Insert с теми же параметрами
4.6.2 Хранимая процедура NewCustomerWithTransaction. В листинге 5 представлена хранимая процедура, добавляющая в базу данных информацию о новом клиенте и регистрирующая покупку им произведения. Эта процедура принимает семь параметров, содержащих данные о новом клиенте и его покупке.
Листинг 5. Хранимая процедура NewCustomerWithTransaction
CREATE PROCEDURE dbo.NewCustomerWithTransaction
@NewName char(25), @NewAreaCode char(3), @NewPhone char(8),
@ArtistName char(25), @WorkTitle char (25), @WorkCopy char (8),
@Price numeric(8,2)
AS
DECLARE @Count as int,
@Aid as int,
@Cid as int,
@Wid as int,
@Tid as int
SELECT @Count=Count(*)
FROM dbo.CUSTOMER
WHERE [Name] = @NewName AND AreaCode = @NewAreaCode AND
PhoneNumber=@NewPhone;
IF @Count > 0
BEGIN
PRINT 'Клиент уже есть в базе данных - никаких действий не предпринято' RETURN
END
BEGIN TRANSACTION /* Начинаем транзакцию: если есть проблемы, производим откат */
INSERT INTO dbo.CUSTOMER ([Name], AreaCode, PhoneNumber)
VALUES (@NewName, @NewAreaCode, @NewPhone);
SELECT @Cid=CustomerID
FROM dbo.CUSTOMER
WHERE [Name] = @NewName AND AreaCode = @NewAreaCode AND
PhoneNumber = @NewPhone;
SELECT @Aid=ArtistID
FROM dbo.Artist
WHERE ArtistName = @ArtistName
IF @Aid IS NULL /* Неправильный ArtistID */
BEGIN
Print 'Неправильное значение ArtistID'
ROLLBACK
RETURN
END
SELECT @Wid=WorkID
FROM dbo.[WORK]
WHERE ArtistID = @Aid AND Title = @WorkTitle AND Copy = @WorkCopy
IF @Wid IS NULL /* Неправильный WorkID */
BEGIN
Print 'Неправильное значение WorkID'
ROLLBACK
RETURN
END
SELECT @Tid=TransactionID
FROM dbo.[TRANS]
WHERE WorkID = @Wid AND SalesPrice IS NULL
IF @Tid IS NULL /* Неправильный TransactionID */
BEGIN
Print 'Нет ни одной транзакции'
ROLLBACK
RETURN
END
UPDATE dbo.[TRANS] /* Все в порядке, обновляем строку в таблице TRANS */SET PurchaseDate = GETDATE(), SalesPrice = @Price, CustomerID = @Cid
WHERE TransactionID = @Tid
INSERT INTO dbo.[CUSTOMER_ARTIST_INT] (ArtistID, CustomerID)
VALUES (@Aid, @Cid)
COMMIT
Первое, что нужно сделать, – это проверить, не существует ли уже этот клиент в базе данных; если да, то процедура завершает работу с сообщением об ошибке. Если этого клиента нет в базе данных, процедура начинает транзакцию. Транзакции гарантируют атомарность действий, выполняемых с базой данных: либо выполняются все обновления, либо не выполняется ни одного. Итак, начинается транзакция, и в таблицу CUSTOMER вставляется строка для нового клиента. Далее считывается новое значение CustomerID, как показано выше. Затем процедура проверяет допустимость значений ArtistID, WorkID и TransactionID. Если хотя бы одно из них является некорректным, происходит откат транзакции.
Если все перечисленные значения правильны, оператор UPDATE обновляет столбцы PurchaseDate, Price и CustomerID в соответствующей строке таблицы TRANS. В столбец PurchaseDate записывается системная дата (с помощью системной функции GETDATE()), в столбец SalesPrice — значение параметра @Рriсе, а в столбец CustomerID – значение переменной @Cid. Наконец, добавляется строка в таблицу CUSTOMER_ARTIST_INT, чтобы зарегистрировать интерес клиента к данному художнику. Если до этого момента все идет нормально, транзакция сохраняется.
На рис. 4.5 показан вызов этой процедуры с тестовыми данными.
exec NewCustomerWithTransaction
@NewName='Иванов Иван', @NewAreaCode='203', @NewPhone='2242-2678',
@ArtistName=Дэвид Шор', @WorkTitle=Доктор Хаус',
@WorkCopy='1', @Price=100000
Рис. 4.5 Вызов процедуры NewCustomerWithTransaction