Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Посібник Мова SQL кредитно-модульний.doc
Скачиваний:
35
Добавлен:
01.05.2015
Размер:
1.25 Mб
Скачать

Приклади програмування збережених процедур

Збережені процедури істотно розширюють можливості програмування мовою Transact-SQL. У наступних прикладах детальніше розглянемо використанню вхідних і вихідних параметрів.

Параметри і змінні - основа динамічності збережених процедур. Вхідні параметри дозволяють користувачеві, що виконує процедуру, передавати процедурі різні значення і одержувати в кожному випадку конкретні унікальні результати. Вихідні параметри дозволяють одержувати не тільки результуючий набір, але й додаткові відомості. Під час виконання процедури значення вихідних параметрів зберігаються в пам'яті. Щоб одержати значення вихідного параметра, необхідно створити змінну для його зберігання. Отримане значення можна відобразити за допомогою команд SELECTіPRINTабо використати його для виконання інших команд процедури.

Вхідні параметри ми вже застосовували раніше - при створенні збереженої процедури CustOrderHistRepвикористали вхідний параметр@CustomerID, якому перед виконанням процедури привласнювали значенняthecr.

Вхідний параметр визначають у збереженій процедурі, а його значення задають при її виконанні. Вихідний параметр збереженої процедури визначається за допомогою ключового слова OUTPUT. При виконанні процедури значення вихідного параметра зберігається в пам'яті. Щоб використати його, необхідно оголосити змінну для зберігання цього значення. Як правило, вихідні значення відображаються після завершення виконання процедури. Використання вхідних і вихідних параметрів ілюструє наступна процедура:

USE Pubs

GO

CREATE PROCEDURE dbo.SalesForTitle

@Title varchar(80),

@YtdSales int OUTPUT,

@TitleText varchar(80) OUTPUT

AS

SELECT @YtdSales = ytd_sales, @TitleText=title

FROM titles WHERE title LIKE @Title

GO

@Title- це вхідний параметр, а вихідні —@YtdSalesі@TitleText. Зверніть увагу, що для всіх трьох параметрів визначений тип даних. У визначенні вихідних параметрів присутнє обов'язкове ключове словоOUTPUT. Всі параметри після визначення застосовуються в операторіSELECT. Спочатку значення вихідних параметрів встановлюються рівними іменам стовпців у запиті. Під час виконання запиту у вихідних параметрах будуть зазначені значення із цих двох стовпців. У конструкціїWHEREоператораSELECTє присутнім вхідний параметр@Title. При виконанні цієї процедури необхідно задати значення вхідного параметра, інакше запит не виконається. Наступний оператор виконує процедуруSalesForTitle:

-- Оголосити змінні, що одержують вихідні значення процедури.

DECLARE @y_YtdSales int, @t_TitleText varchar(80)

EXECUTE SalesForTitle

@YtdSales = @y_YtdSales OUTPUT,

@TitleText = @t_TitleText OUTPUT,

@Title = "%Garlic%"

Select "Title" = @t_TitleText. "Number of Sales" = @y_YtdSales

GO

Оголошуються дві змінні: @y_YtdSales і@t_TitleText. Вони одержують значення, які зберігаються у вихідних параметрах. Зверніть увагу, що типи даних, оголошені для цих змінних, збігаються з типами даних відповідних вихідних параметрів. Ці змінні можуть мати ті ж імена, що й вихідні параметри, оскільки в збережених процедурах змінні локальні для пакета, у якому вони оголошені. Для ясності тут використані імена змінних, відмінні від імен вихідних параметрів. При оголошенні змінної її значення не збігається зі значенням вихідного параметра. Значення змінних стають рівними значенням вихідних параметрів лише після виконання оператора EXECUTE. Зверніть увагу, що після присвоєння змінним значень параметрів задане ключове слово OUTPUT. Без нього оператор SELECT, розташований наприкінці пакета, не зможе вивести значення змінних. Зверніть також увагу на значення вхідного параметра@Title, що дорівнює%Garlic%.Це значення передається в конструкцію WHERE оператора SELECT збереженої процедури. Оскільки в конструкції WHERE зазначене ключове словоLIKE, можна використати знаки підстановки, наприклад%. Отриманий у результаті запит настроєний на пошук заголовків, у яких утримується слово«Garlic».

Нижче показаний більше простий спосіб виконання процедури. Зверніть увагу, що зовсім не обов'язково явно привласнювати змінним збереженої процедури значення вхідного параметра або оголошених тут вихідних змінних:

DECLARE @y_YtdSales int, @t_TitleText varchar(80)

EXECUTE SalesForTitle

"%Garlic%"

@y_YtdSales OUTPUT,

@t_TitleText OUTPUT

Select "Title" = @t_TitleText, "Number of Sales" = @y_YtdSales

GO

Особливість цієї процедури в тім, що вона повертає єдиний рядок. Навіть якщо оператор SELECTіз процедури повертає кілька рядків, у кожної змінній зберігається тільки одне значення (дані з останнього повернутого рядка). Способи рішення цієї проблеми, описані далі.

Оператор RETURN і обробка помилок

Часто основні зусилля при програмуванні якісних збережених процедур (та й будь-яких програм) витрачаються на реалізацію обробки помилок. SQL Server надає функції і оператори для обробки помилок, що виникають під час виконання процедури. Помилки можна розділити на дві основні категорії: пов'язані з комп'ютерами, наприклад, коли недоступний сервер баз даних, і користувальницькі. Для обробки помилок, що виникають під час виконання процедур, використовуються коди повернення й функція @@ERROR.

Коди повернення придатні не тільки для обробки помилок. Оператор RETURNвикористовується для генерації кодів повернення і виходу з пакету, він може повернути програмі, яка викликала процедуру будь-яке цілочислене значення. У цьому розділі показані приклади програм, у яких операторRETURNповертає значення для обробки помилок і інших цілей. ОператорRETURNвикористовується головним чином для обробки помилок, оскільки при виконанні цього оператора виконується безумовний вихід із процедури.

Для користувача більш корисне повідомлення про відсутність записів, що відповідають запиту. У наступному прикладі показано, як модифікувати збережену процедуру SalesEorTitle, щоб задіяти операторRETURN(і створити більше інформативне повідомлення для користувача):

ALTER PROCEDURE dbo.SalesForTitle

@Title varchar(80),

@YtdSales int OUTPUT.

@TitleText varchar(80) OUTPUT

AS

IF (SELECT COUNT(*) FROM titles WHERE title LIKE @Title) = 0

RETURN(1)

ELSE

SELECT @YtdSales = ytd_sales, @TitleText=title

FROM titles WHERE title LIKE @Title

GO

Оператор IF після ключового словаASвизначає, чи заданий вхідний параметр при виконанні процедури і чи відповідають йому які-небудь записи в базі даних. Якщо функціяCOUNTповертає 0, то код повернення встановлюється рівним 1:RETURN(1). Якщо функціяCOUNTповертає значення, відмінне від 0, то операторSELECTзапитує з таблиціTitlesрічний обсяг продажу і відомості про видання. У цьому випадку код повернення дорівнює 0.

Щоб задіяти коди повернення, прийде перепрограмувати оператори для виконання процедури. У наступному прикладі вхідному параметру @Title привласнюється значення Garlic%;

DECLARE @y_YtdSales int, @t_Titl-@Text varchar(80), @r_Code int

EXECUTE @r_Code = SalesForTitle

@YtdSales = @y_YtdSales OUTPUT,

@TitleText = @t_TitleText OUTPUT

@Title = "Garlic%"

IF @r_Code = 0

SELECT "Title" = @t_TitleText,

"Number of Sales" = @y_YtdSales,

"Return Code" = @r_Code

ELSE IF @r_Code = 1

PRINT 'No matching titles in the database. Return code=' + CONVERT(varchar(1),ir_Code)

GO

До оператора DECLAREбула додана нова змінна -@r_Code. Далі ця змінна зберігає значення, що повертає операторомRETURN. Вона визначена як цілочислена, оскільки код повернення передається як ціле число. У рядку з операторомEXECUTEзмінній@r_Codeпривласнюється значення коду повернення. Зверніть увагу, що змінна@r_Codeмістить значення, що повертає збережена процедура. Тепер замість%Garlic%для вхідного параметра@Titleзадане значенняGarlic%.Інакше кажучи, операторSELECTбуде шукати в таблиціTitlesвидання, назви яких починаються зі слова “Garlic”. Нижче параметрів і коментарю розміщена умова. Спочатку виконується перевірка галузі операторомIF. Якщо процедура знаходить запис, код повернення дорівнює 0 і виконується операторSELECT. Якщо процедура не знаходить ні одного відповідного запису, змінна@r_Codeдорівнює 1 і виконується операторPRINT. Оскільки в базі даних немає книги, заголовок якої починається зі слова“Garlic”,результат процедури визначає оператор PRINT:

No matching titles in the database. Return code-1

Якщо змінити значення вхідного параметра на %Garlic%і виконати процедуру ще раз, то вона поверне результуючий набір, показаний у наступній таблиці.

Title Number of Sales Return Code

Onions, Leeks, and Garlic: Cooking 375 0

Методи добування наборів даних

У процедурі, яка використовується як приклад, є обмеження: вона може повернути не більше одного рядка даних. Наприклад, якщо вхідний параметр дорівнює «The%», процедура поверне єдиний рядок - останній запис про книгу, заголовок якої починається з«The%».

Виводиться єдиний рядок, оскільки результуючий набір оператора SELECTпередається змінній, здатній зберігати тільки одне значення. Ця проблема має кілька рішень. Найпростіше полягає у відмові від використання вихідних параметрів в операторіSELECTі поверненні при виконанні процедури набору записів, як показано нижче:

ALTER PROCEDURE dbo.SalesForTitle

@Title varchar(80)

AS

SELECT Title = title, [Number of Sales]=ytd_sales

FROM titles WHERE title LIKE @Title

GO

Зверніть увагу, зі збереженої процедури вилучені всі вихідні параметри. Цю просту збережену процедуру можна виконати за допомогою наступного коду:

EXFCUTE SalesForTitle

@Title = "The%"

При виконанні ця процедура повертає результуючий набір, показаний у наступній таблиці.

Title Number of Sales

The Busy Executive's Database Guide 4095

The Gourmet Microwave 22.246

The Psychology of Computer Cooking NULL

Для простоти зі збереженої процедури вилучені фрагменти з кодами повернення, тому стовпець Return Codeвідсутній. У результуючому наборі перераховані всі книги, заголовок яких починається з“The%”.