tsql
-
Upload
eleksdev -
Category
Technology
-
view
1.297 -
download
0
Transcript of tsql
![Page 1: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/1.jpg)
eleks.com eleks.com
Розширення SQLTransact SQL
• Програмні конструкції T-SQL• Процедури та функції• Обробка помилок• Курсори, тимчасові таблички• Динамічний SQL• Транзакції• Тригери
![Page 2: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/2.jpg)
Програмні конструкції T-SQL•Блок-оператор BEGIN {множина операторів} END•Умовний оператор IF {логічний вираз} {1 оператор}[ELSE {1
оператор}]
•Оператор циклу WHILE {логічний вираз} {1 оператор [BREAK][CONTINUE]}
•Оператор зупинки RETURN [ціле число] – повертає стан виконання блоку (0 - success)
•Оператор переходу GOTO мітка – в якому сама мітка має вигляд point:
•Конструкція виконання BEGIN TRY {1 оператор} END TRY
BEGIN CATCH {1 оператор} END CATCH
![Page 3: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/3.jpg)
•Оператор затримки WAITFOR{DELAY[проміжок часу]|TIME[значення типу datetime][,TIMEOUT затримка]}
•Оператор виконання EXECUTE {}• Оголошення (команда DECLARE)
• Присвоєння значень оператор SELECT (можна кільком змінним відразу та використанням джерела даних) або оператор SET
• GO [кількість повторень] – інформує SQL сервер про закінчення пакету інструкцій
Програмні конструкції T-SQL
![Page 4: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/4.jpg)
Процедура (Stored Procedure)Процедури – об’єкт БД, який дозволяє виконувати набір інструкцій
•Керуються операторами CREATE, ALTER та DROP•Допускають наявність параметрі•Можуть повертати значення різними способами:
-OUTPUT параметри-RETURN - коди (лише int значення)-Result Set кожного SELECT’у чи іншої процедури,
викликаної всередині-Через глобальний курсор, оголошений за межами
процедури
![Page 5: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/5.jpg)
Приклад процедуриCREATE PROCEDURE RecalculateBoxOffice
@MovieId intASBEGIN
UPDATE MovieSET BoxOffice = (select sum(cs.profit) from CinemaShow cswhere ca.MovieId = MovieId)WHERE MovieId = @MovieId
ENDGO
Дану процедуру можна викликати наступним чином :exec RecalculateBoxOffice 1
![Page 6: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/6.jpg)
Виклик процедури з іншого пакету:begindeclare @mId intset @mId = 2exec RecalculateBoxOffice @MovieId = @mIdselect BoxOffice from Moviewhere MovieId = @mIdendGO
Оголошення параметру із значенням по замовчуванню:ALTER PROCEDURE RecalculateBoxOffice @MovieId int = 0AS…
Приклад процедури
![Page 7: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/7.jpg)
Перевірка параметрів:ALTER PROCEDURE RecalculateBoxOffice@MovieId int = 0,@UpdatedBoxOffice money OUTPUTASdeclare @err_code intBEGINdeclare @mId intset @mId = isnull( @MovieId, 0)if @mId = 0 -- check input parameterbeginraiserror('Parameter MovieId is empty!', 10, 1)set @err_code = 50001end
Обробка помилок
![Page 8: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/8.jpg)
Перевірка наявності значення:-- check exists needed rowsif not exists(select 1 from Movie
where MovieId = @mId)beginraiserror('Parameter MovieId %d not found!', 10, 1, @mId)set @err_code = 50002goto SP_ENDend-- update tableUPDATE MovieSET BoxOffice = (select sum(cs.Profit) from CinemaShow cswhere cs.MovieId = MovieId)WHERE MovieId = @mId
Обробка помилок
![Page 9: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/9.jpg)
Перевірка виконання оператора:select @row_code = @@ROWCOUNT, @err_code = @@ERRORif @err_code <> 0 -- check errorbeginraiserror(‘BoxOffice was not calculated for %d!',10,1,@mId)goto SP_ENDendif @row_code = 0 -- check update resultsbeginraiserror(‘Nor rows was updated for %d!',10,1,@ mId)set @err_code = 50003goto SP_ENDend
Обробка помилок
![Page 10: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/10.jpg)
Використання конструкції TRY…CATCH :BEGIN TRY -- update table
UPDATE MovieSET BoxOffice = (select sum(cs.Profit)
from CinemaShow cswhere cs.MovieId = MovieId)
WHERE MovieId = @MovieId END TRYBEGIN CATCH -- check error
SELECT ERROR_NUMBER() ErrorNumber, ERROR_SEVERITY() ErrorSeverity, ERROR_STATE() ErrorState, ERROR_PROCEDURE() ErrorProcedure, ERROR_LINE() ErrorLine, ERROR_MESSAGE() ErrorMessage;END CATCH
Обробка помилок
![Page 11: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/11.jpg)
Обробка помилокПовернення результату із процедури :
-- return new valueselect @UpdatedBoxOffice = BoxOffice from Moviewhere MovieId = @mIdreturn 0SP_END:return @err_codeENDGO
Виклик процедури:declare @ResultValue money = 0declare @ResultCode int = 0exec @ResultCode = RecalculateBoxOffice @MovieId = 1, @UpdatedBoxOffice = @ResultValue OUTPUT
select @Res, @Amm
![Page 12: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/12.jpg)
Використання курсору
Обробка множини значень:declare @Amount intdeclare @Price moneyset @Amount = 0declare docDet cursor -- init cursor
FORWARD_ONLY FAST_FORWARD READ_ONLY LOCALfor select Amount, Price
from DocumentDetail where DocumentId = @DocumentIdopen documentDetail -- open cursor for usingfetch next from docDet into @Amount, @Price -- use cursorwhile @@FETCH_STATUS = 0begin
set @Amount = @Amount + @Amount * @Pricefetch next from docDet into @Amount, @Price
endclose docDet -- close cursordeallocate docDet-- free cursor
![Page 13: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/13.jpg)
Використання курсоруТип доступу до курсору LOCAL | GLOBAL Варіанти руху по курсору FORWARD_ONLY | SCROLLСпосіб вичитування до даних
STATIC | KEYSET | DYNAMIC | FAST_FORWARD Варіанти блокування даних під час використання курсору
READ_ONLY | SCROLL_LOCKS | OPTIMISTIC Видавати попередження про неузгодженість типів у курсорі
TYPE_WARNINGЗміна значень в курсорі (або в його окремих колонках)
FOR UPDATE [ OF назви колонок]
![Page 14: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/14.jpg)
Використання курсоруОператор отримання строки з курсору - FETCHFETCH FIRST – отримання першого рядкаFETCH LAST – отримання останнього рядкаFETCH ABSOLUTE – отримання рядка за його порядковим номеромFETCH RELATIVE – використовується для переміщення курсору вперед чи назад на задану кількість рядківFETCH PRIOR – отримання попереднього рядкаFETCH NEXT – отримання наступного рядка (за замовчуванням)
Для варіанту руху FORWARD_ONLY доступний лише FETCH NEXT
![Page 15: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/15.jpg)
Використання тимчасових таблиць
Змінні табличного типу:declare @TempTab table (
Amount int,Price money)
-- insert datainsert into @TempTab (Amount, Price)
select Amount, Pricefrom DocumentDetail where DocumentId = @DocumentId
-- use tableselect @Amount = sum(Amount * Price)
from @TempTab
![Page 16: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/16.jpg)
Використання тимчасових таблиць
Локальні тимчасові таблиці:create table #TempTab (Amountint,Price money)insert into #TempTab (Amount, Price)select Amount, Pricefrom DocumentDetailwhere DocumentId = @DocumentIdselect @Amount = sum(Amount * Price)from #TempTabdrop table #TempTab
Глобальні тимчасові таблиці (##) доступні всім сесіям та процесам
![Page 17: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/17.jpg)
Динамічний SQL (Dynamic SQL) Безпосереднє виконання запитів із стрічки:
exec ('select Name from Client')declare @query varchar(50)set @query = 'select Name from Client ' +
' where ClientId = ' + cast(1 as varchar(2))exec (@query)
Використання процедури sp_executesql:DECLARE @intParameter INTDECLARE @query NVARCHAR(500) -- Build the SQL stringDECLARE @parameterDef NVARCHAR(100) -- Specify the parameter formatSET @query = N'select Name from Client where ClientId = @ClientId'SET @parameterDef = N'@ClientId int'SET @intParameter = 1; -- Execute with the first parameter valueEXECUTE sp_executesql @query, @parameterDef, @ClientId = @intParameterSET @IntParameter = 2; -- Execute the same with the second valueEXECUTE sp_executesql @query, @ParameterDeg, @ClientId = @intParameter
![Page 18: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/18.jpg)
SQL-ін’єкції
![Page 19: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/19.jpg)
ФункціїСкалярні функції, визначені користувачем:
CREATE FUNCTION GetCinemaProfitSum(@MovieId int = 0)RETURNS moneyASBEGINdeclare @result moneyselect @result = sum(Profit) from CinemaShow where MovieId = @MovieIdreturn @resultENDGO
Приклад використання:select dbo. GetCinemaProfitSum(1)
![Page 20: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/20.jpg)
ФункціїПерелік дозволених операторів (виразів) у функціях:• Оператор присвоєння (SELECT, SET)• Всі оператори керування послідовністю дій (if, while, goto, …), окрім
TRY...CATCH виразу.• DECLARE - вирази для оголошення локальних змінних та курсорів• SELECT - вирази повинні повертати данні у змінні • Всі операції з локальними курсорами (OPEN, FETCH, CLOSE,
DEALLOCATE) повинні знаходитися всередині функції, також FETCH - вираз може бути використаний лише для присвоєння значення локальним змінним
• INSERT, UPDATE та DELETE повинні модифікувати лише локальні змінні типу table.
• Оператор EXECUTE викликає лише загальні процедури
![Page 21: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/21.jpg)
ФункціїТабличні функції, визначені користувачем:
CREATE FUNCTION fnClientList(@c_Name varchar(20))RETURNS @resList table (cfName varchar(50))
ASBEGIN
declare @nInt intdeclare @cName varchar(50)set @nInt = 1while @nInt > 0 begin
select top 1 @cName = cName from tClients where cName like (@c_Name + '%')and cName not in (select cfName from @resList)
set @nInt = @@rowcountif @nInt > 0
insert into @resList(cfName) values (@cName)endreturn
ENDGO
Приклад використання:select * from dbo.fnClientList('CL')
![Page 22: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/22.jpg)
Задані користувачем типи•User-defined Data Types•User-defined Table Types
Створення Table типу:create type EmailTable as table(
EmailId int null,EmailAddress nvarchar(256) not null,EmailTypeEnum int not null,IsPrimary bit not null
)
Використання параметром в процедурі:create procedure CreateContact
@FirstName nvarchar(64),@LastName nvarchar(64),@Emails EmailTable readonly,@Phones PhoneTable readonly
as begin--procedure body
end
![Page 23: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/23.jpg)
ТранзакціїОкрема операція або набір операцій, які розглядаються як єдиний ланцюжок дійТранзакція має чотири спеціальні характеристики (властивості ACID):1. Неподільність (ATOMIC) – зв’язані операції можуть
виконуються або всі, або не виконується жодна2. Відповідність (CONSISTENCY) – по закінчені транзакції всі
данні повинні відповідати всім правилам, які накладаються на них в БД, без винятків
3. Ізоляція (ISOLATION) – одна транзакція не може накладатися на іншу (перетинатися з іншою)
4. Довговічність (DURABILITY) – після завершення транзакції всі внесені зміни повинні стати постійними
![Page 24: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/24.jpg)
Транзакції
Чотири режими транзакцій:1. Autocommit (автоматична фіксація транзакцій) – використовується по
замовчуванню, ініціюються SQL-сервером для кожної команди зокрема2. Explicit (явно задані транзакції) – ініціюються та керуються користувачем за
допомогою наступних команд:• BEGIN {TRAN | TRANSACTION} [назва транзакції]• COMMIT {TRAN | TRANSACTION} [назва транзакції]• ROLLBACK {TRAN | TRANSACTION} [назва транзакції]• SAVE {TRAN | TRANSACTION} [назва точки збереження]3. Implicit (неявні транзакції) – режим автоматичної ініціалізації транзакції,
проте явного примусового завершення (регулюється перемикачем SET IMPLICIT_TRANSACTIONS { ON | OFF })
4. Batch-scored (транзакції для виконання пакетів) – специфічний режим для однієї сесії Multiple Active Result Sets (MARS)
![Page 25: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/25.jpg)
Рівні ізольованості транзакцій:Проблеми паралельного виконання транзакцій:
•Втрачене обновлення (lost update)•«Брудне» читання (dirty read)•Неповторюване читання (non-repeatable read)•Фантомне читання (phantom reads)
Встановлення рівня ізоляції:SET TRANSACTION ISOLATION LEVEL [LEVELNAME]
![Page 26: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/26.jpg)
Рівні ізольованості транзакцій:1.Read uncommitted2.Read committed (рівень за замовчуванням в MSSQL)3.Repeatable read4.Serializable
Поведінка при різних рівнях ізольованості:
Рівень ізоляції Втрачене оновлення
«Брудне» читання
Неповторюване читання
Фантомне читання
Read uncommitted + - - -
Read committed + + - -
Repeatable read + + + -
Serializable + + + +
![Page 27: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/27.jpg)
ТранзакціїПриклад транзакції в процедурі:
CREATE PROCEDURE InsertDocumentDetails@DocId int, @ProductId int, @Amount int, @Price money, @DocDetailId int OUTPUTAS…--BEGIN TRYBEGIN TRAN T1INSERT INTO DocumentDetail(DocumentId,ProductId,Amount,Price)VALUES (@Docid,@ProductId,@Amount,@Price)set @DocDetailId = @@IDENTITYUPDATE DocumentSET Amount = Amount + @Amount * @Price
WHERE DocumentId = @DocIdCOMMIT TRAN T1END TRYBEGIN CATCHROLLBACK TRAN T1set @DocDetailId = 0END CATCH--
![Page 28: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/28.jpg)
ТранзакціїОсобливості використання вкладених транзакційСистемна функція @@TRANSCOUNT (BEGIN TRANSACTION збільшує значення цієї змінної на 1, а оператор COMMIT TRANSACTION – зменшує 1)Оператор SAVE TRANSACTION (фіксує певні змін і дає можливість відкочувати стан даних саме до цієї точки)
Відображення впливу всіх операторів на @@TRANSCOUNT:Оператор Вплив
BEGIN TRANSACTION +1COMMIT TRANSACTION -1ROLLBACK TRANSACTION Встановить 0SAVE TRANSACTION “мітка” Без змінROLLBACK TRANSACTION “мітка” Без змін
![Page 29: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/29.jpg)
ТранзакціїПриклад вкладених транзакцій #1:
CREATE PROCEDURE InsertDocumetDetailsTR@DocumentId int, @ProductId int, @Amount int, @Price money,@DocDetailId int OUTPUTASBEGINdeclare @Sum moneydeclare @Res intBEGIN TRYBEGIN TRAN T1 -- begin main tranINSERT INTO DocumentDetail (DocumentId, ProductId, Amount, Price)VALUES (@DocumentId,@ProductId,@Amount,@Price)set @DocumentDetailId = @@IDENTITYset @Sum = @Amount * @Price-- run other procedure
exec @Res = UpdateDocumentTR @DocumentId, @Sum
![Page 30: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/30.jpg)
Приклад вкладених транзакцій #2:CREATE PROCEDURE UpdateDocumentTr
@DocumentId int, @Sum moneyASBEGIN
declare @tranCount int -- choose value before begin our transactionsselect @tranCount = @@TRANCOUNTBEGIN TRYif @tranCount = 0begin tran tr2 -- begin tran for separate modeelsesave tran tr2 -- start save for call modeupdate Documentset Amount = Amount + @Sumwhere DocumentId = @Docif @tranCount = 0 –– commit tran only for separate modecommit tran tr2return 0END TRYBEGIN CATCHrollback tran tr2 –– rollback new tran only return 50010 –– return error codeEND CATCH
END
Транзакції
![Page 31: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/31.jpg)
ТригерТип процедур, який виконується автоматично як частина оператора по зміні даних. Trigger DML створюється для таблиці і зв’язується з однією або кількома подіями модифікації даних (INSERT, UPDATE, DELETE).Основними властивостями тригера можна назвати:
•Можливість порівняння попередньої та наступної версії даних (системні таблиці deleted та inserted)
•Здійснення при потребі відкоту недопустимих змін•Зчитування та зміна даних в інших таблицях•Виконання процедур та функцій
•Функція update() дозволяє перевірити зміну колонки таблички (задається як параметр)
![Page 32: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/32.jpg)
ТригерПриклад тригера:
CREATE TRIGGER DocumentDetailSumON DocumentDetail AFTER INSERT,UPDATE,DELETEASdeclare @oldDocumentId int, @newDocumentId int, @DocumentId intdeclare @oldSum money, @newSum money, @Sum moneyBEGINif update(Price) or update(Amount)beginselect @oldDocumentId=DocumentId, @oldSum=Price*Amountfrom deletedselect @newDocumentId=DocumentId, @newSum=Price*Amountfrom insertedselect @DocumentId = isnull(@oldDocumentId,@newDocumentId),@Sum = isnull(@newSum,0) - isnull(@oldSum,0)exec UpdateDocument @DocumentId, @SumendEND
![Page 33: tsql](https://reader035.fdocuments.net/reader035/viewer/2022081604/589ce6041a28abf86d8b62e1/html5/thumbnails/33.jpg)
Any questions?