Upload
duane-mcbride
View
214
Download
1
Embed Size (px)
Citation preview
What Is a User-defined Function?
• Scalar Functions– Similar to a built-in function
• Multi-Statement Table-valued Functions– Content like a stored procedure – Referenced like a view
• In-Line Table-valued Functions– Similar to a view with parameters– Returns a table as the result of single SELECT
statement
Creating a User-defined Function
USE NorthwindCREATE FUNCTION fn_NewRegion (@myinput nvarchar(30)) RETURNS nvarchar(30)BEGIN IF @myinput IS NULL SET @myinput = 'Not Applicable' RETURN @myinputEND
USE NorthwindCREATE FUNCTION fn_NewRegion (@myinput nvarchar(30)) RETURNS nvarchar(30)BEGIN IF @myinput IS NULL SET @myinput = 'Not Applicable' RETURN @myinputEND
Creating a Function
Using a Scalar User-defined Function
• RETURNS Clause Specifies Data Type• Function Is Defined Within a BEGIN and END
Block• Return Type Is Any Data Type Except text,
ntext, image, cursor, or timestamp
Example of a Scalar User-defined Function
USE NorthwindCREATE FUNCTION fn_DateFormat
(@indate datetime, @separator char(1))RETURNS Nchar(20)ASBEGIN RETURN CONVERT(Nvarchar(20), datepart(mm,@indate)) + @separator + CONVERT(Nvarchar(20), datepart(dd, @indate)) + @separator + CONVERT(Nvarchar(20), datepart(yy, @indate))END
USE NorthwindCREATE FUNCTION fn_DateFormat
(@indate datetime, @separator char(1))RETURNS Nchar(20)ASBEGIN RETURN CONVERT(Nvarchar(20), datepart(mm,@indate)) + @separator + CONVERT(Nvarchar(20), datepart(dd, @indate)) + @separator + CONVERT(Nvarchar(20), datepart(yy, @indate))END
SELECT dbo.fn_DateFormat(GETDATE(), ':')SELECT dbo.fn_DateFormat(GETDATE(), ':')
Creating the Function
Calling the Function
Example of a Multi-Statement Table-valued Function
• Creating the Function
• Calling the Function
USE NorthwindGOCREATE FUNCTION fn_Employees (@length nvarchar(9))RETURNS @fn_Employees table (EmployeeID int PRIMARY KEY NOT NULL, [Employee Name] nvarchar(61) NOT NULL)ASBEGIN IF @length = 'ShortName' INSERT @fn_Employees SELECT EmployeeID, LastName FROM Employees ELSE IF @length = 'LongName' INSERT @fn_Employees SELECT EmployeeID, (FirstName + ' ' + LastName) FROM EmployeesRETURNEND
USE NorthwindGOCREATE FUNCTION fn_Employees (@length nvarchar(9))RETURNS @fn_Employees table (EmployeeID int PRIMARY KEY NOT NULL, [Employee Name] nvarchar(61) NOT NULL)ASBEGIN IF @length = 'ShortName' INSERT @fn_Employees SELECT EmployeeID, LastName FROM Employees ELSE IF @length = 'LongName' INSERT @fn_Employees SELECT EmployeeID, (FirstName + ' ' + LastName) FROM EmployeesRETURNEND
SELECT * FROM dbo.fn_Employees('LongName')OrSELECT * FROM dbo.fn_Employees('ShortName')
SELECT * FROM dbo.fn_Employees('LongName')OrSELECT * FROM dbo.fn_Employees('ShortName')
Example of an In-Line Table-valued Function
Creating the Function
Calling the Function Using a Parameter
USE NorthwindGOCREATE FUNCTION fn_CustomerNamesInRegion ( @RegionParameter nvarchar(30) )RETURNS tableASRETURN ( SELECT CustomerID, CompanyName FROM Northwind.dbo.Customers WHERE Region = @RegionParameter )
USE NorthwindGOCREATE FUNCTION fn_CustomerNamesInRegion ( @RegionParameter nvarchar(30) )RETURNS tableASRETURN ( SELECT CustomerID, CompanyName FROM Northwind.dbo.Customers WHERE Region = @RegionParameter )
SELECT * FROM fn_CustomerNamesInRegion(N'WA') SELECT * FROM fn_CustomerNamesInRegion(N'WA')
What Is a Trigger?
• Associated with a Table• Invoked Automatically• Cannot Be Called Directly• Is Part of a Transaction
Uses of Triggers
• Cascade Changes Through Related Tables in a Database
• Enforce More Complex Data Integrity Than a CHECK Constraint
• Define Custom Error Messages• Maintain Denormalized Data• Compare Before and After States of Data Under
Modification
Creating Triggers
• Requires Appropriate Permissions• Cannot Contain Certain Statements
Use NorthwindGOCREATE TRIGGER Empl_Delete ON EmployeesFOR DELETE ASIF (SELECT COUNT(*) FROM Deleted) > 1BEGIN RAISERROR( 'You cannot delete more than one employee at a time.', 16, 1) ROLLBACK TRANSACTIONEND
Use NorthwindGOCREATE TRIGGER Empl_Delete ON EmployeesFOR DELETE ASIF (SELECT COUNT(*) FROM Deleted) > 1BEGIN RAISERROR( 'You cannot delete more than one employee at a time.', 16, 1) ROLLBACK TRANSACTIONEND
How an INSERT Trigger WorksINSERT statement to a table with an INSERT Trigger Defined
INSERT [Order Details] VALUES(10525, 2, 19.00, 5, 0.2)
INSERT [Order Details] VALUES(10525, 2, 19.00, 5, 0.2)
Order DetailsOrder DetailsOrder DetailsOrder Details
OrderIDOrderID
105221052310524
105221052310524
ProductIDProductID
10417
10417
UnitPriceUnitPrice
31.009.6530.00
31.009.6530.00
QuantityQuantity
7924
7924
DiscountDiscount
0.20.150.0
0.20.150.0
5 19.002 0.210523
Insert statement logged
insertedinsertedinsertedinserted
1052310523 22 19.0019.00 55 0.20.2
TRIGGER Actions Execute
Order DetailsOrder DetailsOrder DetailsOrder Details
OrderIDOrderID
105221052310524
105221052310524
ProductIDProductID
10417
10417
UnitPriceUnitPrice
31.009.6530.00
31.009.6530.00
QuantityQuantity
7924
7924
DiscountDiscount
0.20.150.0
0.20.150.0
5 19.002 0.210523
Trigger Code:USE NorthwindCREATE TRIGGER OrdDet_InsertON [Order Details]FOR INSERTASUPDATE P SET UnitsInStock = (P.UnitsInStock – I.Quantity)FROM Products AS P INNER JOIN Inserted AS ION P.ProductID = I.ProductID
Trigger Code:USE NorthwindCREATE TRIGGER OrdDet_InsertON [Order Details]FOR INSERTASUPDATE P SET UnitsInStock = (P.UnitsInStock – I.Quantity)FROM Products AS P INNER JOIN Inserted AS ION P.ProductID = I.ProductID
UPDATE P SET UnitsInStock = (P.UnitsInStock – I.Quantity)FROM Products AS P INNER JOIN Inserted AS ION P.ProductID = I.ProductID
ProductsProductsProductsProducts
ProductIDProductID UnitsInStockUnitsInStock …… ……
1234
1234
15106520
15106520
2 15
INSERT Statement to a Table with an INSERTTrigger Defined
INSERT Statement Logged
Trigger Actions Executed
1111
2222
3333
How a DELETE Trigger WorksDELETE Statement to a table with a DELETE Trigger DefinedDELETE Statement to a table with a DELETE Trigger Defined
DeletedDeletedDeletedDeleted
44 Dairy ProductsDairy Products CheesesCheeses 0x15…0x15…
DELETE statement logged
CategoriesCategoriesCategoriesCategories
CategoryIDCategoryID
123
123
CategoryNameCategoryName
BeveragesCondimentsConfections
BeveragesCondimentsConfections
DescriptionDescription
Soft drinks, coffees…Sweet and savory …Desserts, candies, …
Soft drinks, coffees…Sweet and savory …Desserts, candies, …
PicturePicture
0x15…0x15…0x15…
0x15…0x15…0x15… 0x15…CheesesDairy Products4
DELETE CategoriesWHERE CategoryID = 4
DELETE CategoriesWHERE CategoryID = 4
USE NorthwindCREATE TRIGGER Category_Delete
ON CategoriesFOR DELETE
ASUPDATE P SET Discontinued = 1FROM Products AS P INNER JOIN deleted AS dON P.CategoryID = d.CategoryID
USE NorthwindCREATE TRIGGER Category_Delete
ON CategoriesFOR DELETE
ASUPDATE P SET Discontinued = 1FROM Products AS P INNER JOIN deleted AS dON P.CategoryID = d.CategoryID
ProductsProductsProductsProducts
ProductIDProductID DiscontinuedDiscontinued …… ……
1234
1234
0000
0000
Trigger Actions Execute
2 1
UPDATE P SET Discontinued = 1FROM Products AS P INNER JOIN deleted AS dON P.CategoryID = d.CategoryID
DELETE Statement to a Table with a DELETEStatement Defined
DELETE Statement Logged
Trigger Actions Executed
1111
2222
3333
How an UPDATE Trigger WorksUPDATE Statement to a table with an UPDATE Trigger Defined
UPDATE EmployeesSET EmployeeID = 17WHERE EmployeeID = 2
UPDATE EmployeesSET EmployeeID = 17WHERE EmployeeID = 2
UPDATE Statement logged as INSERT and DELETE Statements
EmployeesEmployeesEmployeesEmployees
EmployeeIDEmployeeID LastNameLastName FirstNameFirstName TitleTitle HireDateHireDate
1234
1234
DavolioBarrLeverlingPeacock
DavolioBarrLeverlingPeacock
NancyAndrewJanetMargaret
NancyAndrewJanetMargaret
Sales Rep.RSales Rep.Sales Rep.
Sales Rep.RSales Rep.Sales Rep.
~~~~~~~~~~~~
~~~~~~~~~~~~
2 Fuller Andrew Vice Pres. ~~~
insertedinsertedinsertedinserted
1717 FullerFuller AndrewAndrew Vice Pres.Vice Pres. ~~~~~~
deleteddeleteddeleteddeleted
22 FullerFuller AndrewAndrew Vice Pres.Vice Pres. ~~~~~~
TRIGGER Actions Execute
USE NorthwindGOCREATE TRIGGER Employee_Update
ON EmployeesFOR UPDATE
ASIF UPDATE (EmployeeID)BEGIN TRANSACTION
RAISERROR ('Transaction cannot be processed.\***** Employee ID number cannot be modified.', 10, 1)ROLLBACK TRANSACTION
USE NorthwindGOCREATE TRIGGER Employee_Update
ON EmployeesFOR UPDATE
ASIF UPDATE (EmployeeID)BEGIN TRANSACTION
RAISERROR ('Transaction cannot be processed.\***** Employee ID number cannot be modified.', 10, 1)ROLLBACK TRANSACTION
ASIF UPDATE (EmployeeID)BEGIN TRANSACTIONRAISERROR ('Transaction cannot be processed.\***** Employee ID number cannot be modified.', 10, 1)ROLLBACK TRANSACTION
Transaction cannot be processed. ***** Member number cannot be modified Transaction cannot be processed. ***** Member number cannot be modified
EmployeesEmployeesEmployeesEmployees
EmployeeIDEmployeeID LastNameLastName FirstNameFirstName TitleTitle HireDateHireDate
1234
1234
DavolioBarrLeverlingPeacock
DavolioBarrLeverlingPeacock
NancyAndrewJanetMargaret
NancyAndrewJanetMargaret
Sales Rep.RSales Rep.Sales Rep.
Sales Rep.RSales Rep.Sales Rep.
~~~~~~~~~~~~
~~~~~~~~~~~~
2 Fuller Andrew Vice Pres. ~~~
UPDATE Statement to a Table with an UPDATETrigger Defined
UPDATE Statement Logged as INSERT andDELETE Statements
Trigger Actions Executed
1111
2222
3333
How an INSTEAD OF Trigger WorksCreate a View That Combines Two or More Tables
CREATE VIEW Customers ASSELECT * FROM CustomersMexUNIONSELECT * FROM CustomersGer
CREATE VIEW Customers ASSELECT * FROM CustomersMexUNIONSELECT * FROM CustomersGer
CustomersMexCustomersMexCustomersMexCustomersMex
CustomerIDCustomerID CompanyNameCompanyName CountryCountry PhonePhone ……
ANATRANTONCENTC
ANATRANTONCENTC
Ana Trujill…Antonio M…Centro Co…
Ana Trujill…Antonio M…Centro Co…
MexicoMexicoMexico
MexicoMexicoMexico
(5) 555-4729(5) 555-3932(5) 555-3392
(5) 555-4729(5) 555-3932(5) 555-3392
~~~~~~~~~
~~~~~~~~~
CustomersGerCustomersGerCustomersGerCustomersGer
CustomerIDCustomerID CompanyNameCompanyName CountryCountry PhonePhone ……
ALFKIBLAUSDRACD
ALFKIBLAUSDRACD
Alfreds Fu…Blauer Se…Drachenb…
Alfreds Fu…Blauer Se…Drachenb…
GermanyGermanyGermany
GermanyGermanyGermany
030-00743210621-084600241-039123
030-00743210621-084600241-039123
~~~~~~~~~
~~~~~~~~~
INSTEAD OF trigger directs the update to the base table
CustomersCustomersCustomersCustomers
CustomerIDCustomerID CompanyNameCompanyName CountryCountry PhonePhone ……
ALFKIANATRANTON
ALFKIANATRANTON
Alfreds Fu…Ana Trujill…Antonio M…
Alfreds Fu…Ana Trujill…Antonio M…
GermanyMexicoMexico
GermanyMexicoMexico
030-0074321(5) 555-4729(5) 555-3932
030-0074321(5) 555-4729(5) 555-3932
~~~~~~~~~
~~~~~~~~~
Original Insert to the Customers View Does Not Occur
UPDATE is Made to the View
ALFKI Alfreds Fu… Germany 030-0074321 ~~~
ALFKI Alfreds Fu… Germany 030-0074321 ~~~
INSTEAD OF Trigger Can Be on a Table or View
The Action That Initiates the Trigger Does NOT Occur
Allows Updates to Views Not Previously Updateable
1111
2222
3333
• Examples of Triggers
• Enforcing Data Integrity• Enforcing Business Rules
Enforcing Data IntegrityCREATE TRIGGER BackOrderList_Delete
ON Products FOR UPDATEASIF (SELECT BO.ProductID FROM BackOrders AS BO JOIN
Inserted AS I ON BO.ProductID = I.Product_ID) > 0
BEGINDELETE BO FROM BackOrders AS BO INNER JOIN Inserted AS I ON BO.ProductID = I.ProductID
END
CREATE TRIGGER BackOrderList_DeleteON Products FOR UPDATE
ASIF (SELECT BO.ProductID FROM BackOrders AS BO JOIN
Inserted AS I ON BO.ProductID = I.Product_ID) > 0
BEGINDELETE BO FROM BackOrders AS BO INNER JOIN Inserted AS I ON BO.ProductID = I.ProductID
END
ProductsProductsProductsProducts
ProductIDProductID UnitsInStockUnitsInStock …… ……
1
34
1
34
15106520
15106520
2 15 UpdatedUpdated
BackOrdersBackOrdersBackOrdersBackOrders
ProductIDProductID UnitsOnOrderUnitsOnOrder ……
1123
1123
151065
151065
2 15 Trigger Deletes RowTrigger Deletes Row
ProductsProductsProductsProducts
ProductIDProductID UnitsInStockUnitsInStock …… ……
1234
1234
15106520
15106520
Enforcing Business Rules Products with Outstanding Orders Cannot Be Deleted
IF (Select Count (*) FROM [Order Details] INNER JOIN deleted ON [Order Details].ProductID = deleted.ProductID ) > 0ROLLBACK TRANSACTION
IF (Select Count (*) FROM [Order Details] INNER JOIN deleted ON [Order Details].ProductID = deleted.ProductID ) > 0ROLLBACK TRANSACTION
DELETE statement executed on Product table
Trigger codechecks the Order Detailstable
Order DetailsOrder DetailsOrder DetailsOrder Details
OrderIDOrderID
10522105231052410525
10522105231052410525
ProductIDProductID
102417
102417
UnitPriceUnitPrice
31.0019.009.6530.00
31.0019.009.6530.00
QuantityQuantity
7924
7924
DiscountDiscount
0.20.150.0
0.20.150.0
9
'Transaction cannot be processed''This product has order history'
'Transaction cannot be processed''This product has order history'
Transactionrolled back
ProductsProductsProductsProducts
ProductIDProductID UnitsInStockUnitsInStock …… ……
1
34
1
34
15106520
15106520
2 0