Learning Unit 8 UserDefined Functions in Microsoft SQL

  • Slides: 36
Download presentation
Learning Unit 8 User-Defined Functions in Microsoft SQL Server 2005 Mount Vernon Data Systems

Learning Unit 8 User-Defined Functions in Microsoft SQL Server 2005 Mount Vernon Data Systems LLC dedicated to keeping your SQL Server-powered business systems running

What is a User-Defined Function (UDF)? a mechanism for extending the functionality of the

What is a User-Defined Function (UDF)? a mechanism for extending the functionality of the SQL Server a compiled subroutine that encapsulates code for re-use performs calculations and computations returns a value scalar (single value or NULL) table value (zero+ rows, 1+ columns) first introduced with SQL Server 2000 expanded functionality with each SQL Server release can be coded in T-SQL or CLR (. NET language of your choice) © Mount Vernon Data Systems LLC 2010 All Rights Reserved 2

Difference Between a UDF & a Stored Proc Stored procedure is explicitly called exec

Difference Between a UDF & a Stored Proc Stored procedure is explicitly called exec usp_My. Stored. Procedure it can modify data or database objects UDF is built into the SQL Server environment can be incorporated into queries, stored procedures, computed columns, constraints can return a value while changing nothing else in the database • • cannot modify data in tables cannot change database state cannot create or access temp tables (#table, ##table) cannot modify the database or any external resource (file) no error-checking in a UDF • • an error will cause execution of the UDF to stop which, in turn, causes the statement which invoked the UDF to be cancelled © Mount Vernon Data Systems LLC 2010 All Rights Reserved 3

UDF Life Cycle Create UDF scalar UDFs table-valued UDFs Alter UDF can modify existing

UDF Life Cycle Create UDF scalar UDFs table-valued UDFs Alter UDF can modify existing UDF without dropping & recreating • • retains security permissions and settings will not affect any dependent functions, stored procedures, or triggers Drop UDF will fail if… • • • there are indexed computed columns that reference the function there are functions or views created with SCHEMABINDING that reference the function there are check or default constraints that reference the function © Mount Vernon Data Systems LLC 2010 All Rights Reserved 4

Where Are UDFs Stored in the Database? USE Adventure. Works GO -- display information

Where Are UDFs Stored in the Database? USE Adventure. Works GO -- display information about the UDFs in Adventure. Works -select * from sys. objects where type IN ('AF', 'FN', 'FS', 'FT', 'IF', 'TA', 'TF') order by name; --- display the parameters associated with each of the UDFs. . . -select o. name AS Function. Name, p. * from sys. objects AS o JOIN sys. parameters as p ON o. object_id = p. object_ID where type IN ('AF', 'FN', 'FS', 'FT', 'IF', 'TA', 'TF') order by o. name; --- display the UDF definition. . . select object_definition(object_id('dbo. ufn. Get. Accounting. End. Date')); select * from syscomments where ID in (select object_id('dbo. ufn. Get. Accounting. End. Date')) © Mount Vernon Data Systems LLC 2010 All Rights Reserved 5

Where Are UDFs Stored in the Database? USE Adventure. Works GO -- display information

Where Are UDFs Stored in the Database? USE Adventure. Works GO -- display information about the UDFs in Adventure. Works -select * from sys. objects where type IN ('AF', 'FN', 'FS', 'FT', 'IF', 'TA', 'TF') order by name; --- display the parameters associated with each of the UDFs. . . -select o. name AS Function. Name, p. * from sys. objects AS o JOIN sys. parameters as p ON o. object_id = p. object_ID where type IN ('AF', 'FN', 'FS', 'FT', 'IF', 'TA', 'TF') order by o. name; --- display the UDF definition. . . select object_definition(object_id('dbo. ufn. Get. Accounting. End. Date')); select * from syscomments where ID in (select object_id('dbo. ufn. Get. Accounting. End. Date')) © Mount Vernon Data Systems LLC 2010 All Rights Reserved 6

Types of UDFs select * from sys. objects where type IN ('AF', 'FN', 'FS',

Types of UDFs select * from sys. objects where type IN ('AF', 'FN', 'FS', 'FT', 'IF', 'TA', 'TF') order by name; AF = Aggregate function (CLR) FN = SQL scalar function, FS = Assembly (CLR) scalar function FT = Assembly (CLR) table-valued function IF = SQL inline table-valued function TA = Assembly (CLR) DML trigger TF = SQL table-valued-function © Mount Vernon Data Systems LLC 2010 All Rights Reserved 7

UDF Operations CREATE FUNCTION owner_name. function_name (parameter_name parameter_data_type, etc. ) RETURNS return_data_type WITH UDF_OPTIONS

UDF Operations CREATE FUNCTION owner_name. function_name (parameter_name parameter_data_type, etc. ) RETURNS return_data_type WITH UDF_OPTIONS AS BEGIN RETURN clause with computation instructions END GO ALTER FUNCTION owner_name. function_name (parameter_name parameter_data_type, etc. ) … GO DROP FUNCTION owner_name. function_name GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 8

UDF Options BEST PRACTICE encryption cannot read UDF code in the database catalog schemabinding

UDF Options BEST PRACTICE encryption cannot read UDF code in the database catalog schemabinding prevents anyone from dropping underlying objects or making schema changes to referenced columns in the UDF execute as defines the security context of the function as it executes returns NULL on NULL input do not invoke the function if a parameter is NULL (result will always be NULL ANSI standard behaviour) improves performance by bypassing UDF execution • eliminates the need to check for NULL input in the UDF called on NULL input (default behaviour) invoke the function even when one of the input parms is NULL © Mount Vernon Data Systems LLC 2010 All Rights Reserved 9

Scalar UDFs return a single (scalar) value or NULL specify where ever a scalar

Scalar UDFs return a single (scalar) value or NULL specify where ever a scalar expression is allowed query, constraint, computed column, inside stored proc, etc. must have BEGIN/END block defining the body of the UDF must provide values for all parameters, even optional ones specify the keyword DEFAULT T-SQL scalar UDFs are typically faster than CLR scalar UDFs consistent with SQL Server’s set-based optimization if exists (select 1 from sysobjects where id = object_id('dbo. udf_F 2 C') and type IN ('AF', 'FN', 'FS', 'FT', 'IF', 'TA', 'TF')) drop function dbo. udf_F 2 C GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 10

Create Scalar UDF, Grant Permission to Execute CREATE FUNCTION dbo. udf_F 2 C (@var.

Create Scalar UDF, Grant Permission to Execute CREATE FUNCTION dbo. udf_F 2 C (@var. F int) RETURNS int WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT AS BEGIN return(@var. F-32)*5/9 END GO -- grant permissions to public group to use the UDF GRANT execute ON dbo. udf_F 2 C to public GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 11

Execute Scalar UDF -- execute the UDF; first declare and set a value for

Execute Scalar UDF -- execute the UDF; first declare and set a value for temperature Fahrenheit declare @var. Temp int set @var. Temp = 32 SELECT @var. Temp AS 'Fahrenheit', dbo. udf_F 2 C(@var. Temp) AS 'Celsius'; declare @var. Temp int set @var. Temp = 212 SELECT @var. Temp AS 'Fahrenheit', dbo. udf_F 2 C(@var. Temp) AS 'Celsius'; declare @var. Temp int set @var. Temp = NULL SELECT @var. Temp AS 'Fahrenheit', dbo. udf_F 2 C(@var. Temp) AS 'Celsius'; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 12

Create Scalar UDF, Multiple Inputs, Cast Output Calculate profit margin as a percent Multiple

Create Scalar UDF, Multiple Inputs, Cast Output Calculate profit margin as a percent Multiple inputs, cast output as different data type CREATE FUNCTION dbo. udf_Profit. Margin (@var. Wholesale. Price money, @var. Retail. Price money) RETURNS decimal(7, 2) WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT AS BEGIN DECLARE @var. Result decimal(7, 2) SET @var. Result = cast((@var. Retail. Price/@var. Wholesale. Price)* 100 AS decimal(7, 2)) RETURN @var. Result END GO GRANT execute ON dbo. udf_Profit. Margin to public GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 13

Execute Scalar UDF, Multiple Inputs, Cast Output declare @var. Wholesale. Price money declare @var.

Execute Scalar UDF, Multiple Inputs, Cast Output declare @var. Wholesale. Price money declare @var. Retail. Price money set @var. Wholesale. Price = 25. 00 set @var. Retail. Price = 50. 00 SELECT @var. Wholesale. Price AS 'Wholesale Price', @var. Retail. Price AS 'Retail Price', dbo. udf_Profit. Margin (25. 00, 50. 00) AS '% Profit Margin'; declare @var. Wholesale. Price money declare @var. Retail. Price money set @var. Wholesale. Price = 5. 00 set @var. Retail. Price = 50. 00 SELECT @var. Wholesale. Price AS 'Wholesale Price', @var. Retail. Price AS 'Retail Price', dbo. udf_Profit. Margin (5. 00, 50. 00) AS '% Profit Margin'; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 14

Scalar UDF, Multiple Inputs, Procedural Logic Categorize authors by region return table of results

Scalar UDF, Multiple Inputs, Procedural Logic Categorize authors by region return table of results CREATE FUNCTION dbo. udf_Author. Region (@var. State char(2)) RETURNS varchar(10) WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT AS BEGIN declare @Var. Result varchar(10) IF (@var. State = 'CA' OR @var. State = 'OR' OR @var. State = 'UT') SET @Var. Result = 'Western' ELSE IF @var. State = 'TN' SET @Var. Result = 'Southern' ELSE IF (@var. State = 'KS' OR @var. State = 'MI' OR @var. State = 'IN') SET @Var. Result = 'Midwestern' ELSE set @Var. Result = 'unknown' RETURN @Var. Result END GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 15

Execute Scalar UDF, Mult. Inputs, Procedural Logic SELECT au_lname + ', ' + au_fname

Execute Scalar UDF, Mult. Inputs, Procedural Logic SELECT au_lname + ', ' + au_fname AS "Full Name", dbo. udf_Author. Region (state) AS "Region" FROM dbo. authors WHERE state = 'MI'; SELECT au_lname + ', ' + au_fname AS "Full Name", dbo. udf_Author. Region (state) AS "Region" FROM dbo. authors WHERE state = ‘CA'; SELECT au_lname + ', ' + au_fname AS "Full Name", dbo. udf_Author. Region (city) AS "Region" FROM dbo. authors WHERE state = ‘CA’; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 16

Execute Scalar UDF, Mult. Inputs, Procedural Logic SELECT au_lname + ', ' + au_fname

Execute Scalar UDF, Mult. Inputs, Procedural Logic SELECT au_lname + ', ' + au_fname AS "Full Name", dbo. udf_Author. Region (state) AS "Region" FROM dbo. authors WHERE state = 'MI'; SELECT au_lname + ', ' + au_fname AS "Full Name", dbo. udf_Author. Region (state) AS "Region" FROM dbo. authors WHERE state = ‘CA'; SELECT au_lname + ', ' + au_fname AS "Full Name", dbo. udf_Author. Region (city) AS "Region" FROM dbo. authors WHERE state = ‘CA’; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 17

Create Scalar UDF, Optional Parameters Extract the first “n” bytes of a string CREATE

Create Scalar UDF, Optional Parameters Extract the first “n” bytes of a string CREATE FUNCTION dbo. udf_Extractor (@var. String varchar(80), @var. Extract int = 1) RETURNS varchar(80) WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT AS BEGIN set @var. String = substring(@var. String, 1, @var. Extract) return @var. String END GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 18

Execute Scalar UDF, Mult. Inputs, Procedural Logic select title, dbo. udf_Extractor(title, 5) from dbo.

Execute Scalar UDF, Mult. Inputs, Procedural Logic select title, dbo. udf_Extractor(title, 5) from dbo. titles; select title, dbo. udf_Extractor(title, default) from dbo. titles; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 19

Table-valued UDFs return a table typically specified in the FROM clause of a SELECT

Table-valued UDFs return a table typically specified in the FROM clause of a SELECT statement Inline table-valued UDFs similar to a view in that the result set is defined by a query can accept input parameters (“parameterized view”) Per-row UDFs SQL Server 2005, allows non-deterministic functions • getdate(), rand() • specified in the SELECT clause Multi-statement table-valued UDFs returns a table variable function routine cannot be expressed as a single query © Mount Vernon Data Systems LLC 2010 All Rights Reserved 20

Create Inline Table-valued UDF return all authors who live in a state… input 2

Create Inline Table-valued UDF return all authors who live in a state… input 2 -letter state code No Begin/End Block CREATE FUNCTION dbo. udf_Authors. From. AState (@var. State char(2)) RETURNS TABLE WITH SCHEMABINDING AS RETURN (SELECT au_fname, au_lname, city, state, zip FROM dbo. authors WHERE state = @var. State) GO SQL Server query processor replaces an Inline UDF reference with its definition & generates an execution plan based on access to the underlying database objects, just like it treats a view. © Mount Vernon Data Systems LLC 2010 All Rights Reserved 21

Execute Inline Table-valued UDF select * from dbo. udf_Authors. From. AState('MI'); select * from

Execute Inline Table-valued UDF select * from dbo. udf_Authors. From. AState('MI'); select * from dbo. udf_Authors. From. AState('CA'); © Mount Vernon Data Systems LLC 2010 All Rights Reserved 22

Create Inline Table-valued UDF with Aggregation return the total number of orders for any

Create Inline Table-valued UDF with Aggregation return the total number of orders for any store input 4 -character store ID CREATE FUNCTION dbo. udf_Sales. By. Store (@var. Store. ID char(4)) RETURNS TABLE WITH SCHEMABINDING AS RETURN ( SELECT s 2. stor_id, s 1. stor_name, SUM(s 2. qty) AS 'Order Total' FROM dbo. Stores s 1 JOIN dbo. Sales s 2 ON s 1. stor_id = s 2. stor_id WHERE s 2. stor_id = @var. Store. ID GROUP BY s 2. stor_id, s 1. stor_name ) GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 23

Execute Inline Table-valued UDF with Aggregation select * from dbo. udf_Sales. By. Store(6380); select

Execute Inline Table-valued UDF with Aggregation select * from dbo. udf_Sales. By. Store(6380); select * from dbo. udf_Sales. By. Store(7131); select * from dbo. udf_Sales. By. Store(8042); © Mount Vernon Data Systems LLC 2010 All Rights Reserved 24

Create Per-row Table-valued UDF with Get. Date() non-deterministic functions allowed with SQL Server 2005

Create Per-row Table-valued UDF with Get. Date() non-deterministic functions allowed with SQL Server 2005 determined once, returned for each row in the entire result set CREATE FUNCTION dbo. udf_Get. Date() RETURNS datetime WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT AS BEGIN RETURN getdate(); END GO -- grant permissions to groups to use the UDF GRANT execute ON dbo. udf_Get. Date to public GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 25

Execute Per-row Table-valued UDF with Get. Date() SELECT ord_num, dbo. udf_Get. Date() AS 'Current

Execute Per-row Table-valued UDF with Get. Date() SELECT ord_num, dbo. udf_Get. Date() AS 'Current Date & Time' FROM dbo. Sales; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 26

Create Per-row Table-valued UDF with Day() deterministic functions resolved for each row different value,

Create Per-row Table-valued UDF with Day() deterministic functions resolved for each row different value, depending on input CREATE FUNCTION dbo. udf_day(@var. Date datetime) RETURNS int WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT AS BEGIN RETURN day(@var. Date); END GO -- grant permissions to groups to use the UDF GRANT execute ON dbo. udf_day to public GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 27

Execute Per-row Table-valued UDF with Day() SELECT ord_num, ord_date, dbo. udf_day(ord_date) AS 'Day Number'

Execute Per-row Table-valued UDF with Day() SELECT ord_num, ord_date, dbo. udf_day(ord_date) AS 'Day Number' FROM dbo. Sales; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 28

Create Multi-Statement Table-valued UDF create a reporting hierarchy layout… list all employees who report

Create Multi-Statement Table-valued UDF create a reporting hierarchy layout… list all employees who report to the individual specified USE Adventure. Works GO CREATE FUNCTION dbo. udf_Reporting. Hierarchy (@In. Emp. ID INTEGER) RETURNS @var. Rep. Hierarchy TABLE ( Employee. ID int primary key NOT NULL, Name nvarchar(255) NOT NULL, Title nvarchar(50) NOT NULL, Employee. Level int NOT NULL, Sort nvarchar (255) NOT NULL ) WITH SCHEMABINDING AS © Mount Vernon Data Systems LLC 2010 All Rights Reserved 29

Create Multi-Statement Table-valued UDF BEGIN WITH Rep. Hierarchy(Name, Title, Employee. ID, Employee. Level, Sort)

Create Multi-Statement Table-valued UDF BEGIN WITH Rep. Hierarchy(Name, Title, Employee. ID, Employee. Level, Sort) AS (SELECT convert(varchar(255), c. First. Name + ' ' + c. Last. Name), e. Title, e. Employee. ID, 1, convert(varchar(255), c. First. Name + ' ' + c. Last. Name) FROM Human. Resources. Employee AS e JOIN Person. Contact AS c ON e. Contact. ID = c. Contact. ID WHERE e. Employee. ID = @In. Emp. ID UNION ALL SELECT convert(varchar(255), replicate ('| ' , Employee. Level)+c. First. Name + ' ' + c. Last. Name), e. Title, e. Employee. ID, Employee. Level + 1, convert (Varchar(255), rtrim(sort) + '| ' + First. Name + ' ' + Last. Name) FROM Human. Resources. Employee as e JOIN Person. Contact AS c ON e. Contact. ID = c. Contact. ID JOIN Rep. Hierarchy AS d ON e. Manager. ID = d. Employee. ID ) © Mount Vernon Data Systems LLC 2010 All Rights Reserved 30

Create Multi-Statement Table-valued UDF -- second query -- copy the generated columns to the

Create Multi-Statement Table-valued UDF -- second query -- copy the generated columns to the result of the function INSERT @var. Rep. Hierarchy SELECT Employee. ID, Name, Title, Employee. Level, Sort FROM Rep. Hierarchy RETURN END GO © Mount Vernon Data Systems LLC 2010 All Rights Reserved 31

Execute Multi-Statement Table-valued UDF with Day() SELECT Employee. ID, Name, Title, Employee. Level FROM

Execute Multi-Statement Table-valued UDF with Day() SELECT Employee. ID, Name, Title, Employee. Level FROM dbo. udf_Reporting. Hierarchy(109) ORDER BY Sort; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 32

Execute Multi-Statement Table-valued UDF with Day() SELECT Employee. ID, Name, Title, Employee. Level FROM

Execute Multi-Statement Table-valued UDF with Day() SELECT Employee. ID, Name, Title, Employee. Level FROM dbo. udf_Reporting. Hierarchy(109) ORDER BY Sort; SELECT Employee. ID, Name, Title, Employee. Level FROM dbo. udf_Reporting. Hierarchy(273) ORDER BY Sort; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 33

Execute Multi-Statement Table-valued UDF with Day() SELECT Employee. ID, Name, Title, Employee. Level FROM

Execute Multi-Statement Table-valued UDF with Day() SELECT Employee. ID, Name, Title, Employee. Level FROM dbo. udf_Reporting. Hierarchy(109) ORDER BY Sort; SELECT Employee. ID, Name, Title, Employee. Level FROM dbo. udf_Reporting. Hierarchy(273) ORDER BY Sort; SELECT Employee. ID, Name, Title, Employee. Level FROM dbo. udf_Reporting. Hierarchy(284) ORDER BY Sort; © Mount Vernon Data Systems LLC 2010 All Rights Reserved 34

Reasons To Use a UDF modular programming write once, use many reusable code, can

Reasons To Use a UDF modular programming write once, use many reusable code, can be modified independently of calling program faster execution pre-compiled, caches the execution plan & reuses for repeated executions reduce network traffic filter data based on some complex constraint that is best expressed via UDF invoke UDF in the WHERE clause © Mount Vernon Data Systems LLC 2010 All Rights Reserved 35

The Author… Michelle A. Poolet, MCIS, University of Denver Zachman Certified™ - Enterprise Architect

The Author… Michelle A. Poolet, MCIS, University of Denver Zachman Certified™ - Enterprise Architect Contributing Editor, SQL Server Magazine Adjunct faculty, University of Denver, University College President/co-founder of Mount Vernon Data Systems – database consulting company specializing in database systems, data modeling, courseware development, education/training. Michelle@Mount. Vernon. Data. Systems. com Hanging out near the beach at Kailua. Kona, Hawaii…aloha, everyone! © Mount Vernon Data Systems LLC 2010 All Rights Reserved 36