Download User-Defined Functions | Microsoft Docs

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Database model wikipedia , lookup

Relational model wikipedia , lookup

Open Database Connectivity wikipedia , lookup

SQL wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

Object-relational impedance mismatch wikipedia , lookup

PL/SQL wikipedia , lookup

Transcript
Table of Contents
Overview
Deterministic and Nondeterministic Functions
Create User-defined Functions (Database Engine)
Create CLR Functions
Create User-defined Aggregates
Modify User-defined Functions
Delete User-defined Functions
Execute User-defined Functions
Rename User-defined Functions
View User-defined Functions
User-Defined Functions
5/4/2017 • 5 min to read • Edit Online
Like functions in programming languages, SQL Server user-defined functions are routines that accept parameters,
perform an action, such as a complex calculation, and return the result of that action as a value. The return value
can either be a single scalar value or a result set.
User-defined functions
Why use them?
They allow modular programming.
You can create the function once, store it in the database, and call it any number of times in your program.
User-defined functions can be modified independently of the program source code.
They allow faster execution.
Similar to stored procedures, Transact-SQL user-defined functions reduce the compilation cost of TransactSQL code by caching the plans and reusing them for repeated executions. This means the user-defined
function does not need to be reparsed and reoptimized with each use resulting in much faster execution
times.
CLR functions offer significant performance advantage over Transact-SQL functions for computational tasks,
string manipulation, and business logic. Transact-SQL functions are better suited for data-access intensive
logic.
They can reduce network traffic.
An operation that filters data based on some complex constraint that cannot be expressed in a single scalar
expression can be expressed as a function. The function can then invoked in the WHERE clause to reduce the
number or rows sent to the client.
NOTE
Transact-SQL user-defined functions in queries can only be executed on a single thread (serial execution plan).
Types of functions
Scalar Function
User-defined scalar functions return a single data value of the type defined in the RETURNS clause. For an inline
scalar function, there is no function body; the scalar value is the result of a single statement. For a multistatement
scalar function, the function body, defined in a BEGIN...END block, contains a series of Transact-SQL statements that
return the single value. The return type can be any data type except text, ntext, image, cursor, and timestamp.
Examples.
Table-Valued Functions
User-defined table-valued functions return a table data type. For an inline table-valued function, there is no
function body; the table is the result set of a single SELECT statement. Examples.
System Functions
SQL Server provides many system functions that you can use to perform a variety of operations. They cannot be
modified. For more information, see Built-in Functions (Transact-SQL), System Stored Functions (Transact-SQL),
and Dynamic Management Views and Functions (Transact-SQL).
Guidelines
Transact-SQL errors that cause a statement to be canceled and continue with the next statement in the module
(such as triggers or stored procedures) are treated differently inside a function. In functions, such errors cause the
execution of the function to stop. This in turn causes the statement that invoked the function to be canceled.
The statements in a BEGIN...END block cannot have any side effects. Function side effects are any permanent
changes to the state of a resource that has a scope outside the function such as a modification to a database table.
The only changes that can be made by the statements in the function are changes to objects local to the function,
such as local cursors or variables. Modifications to database tables, operations on cursors that are not local to the
function, sending e-mail, attempting a catalog modification, and generating a result set that is returned to the user
are examples of actions that cannot be performed in a function.
NOTE
If a CREATE FUNCTION statement produces side effects against resources that do not exist when the CREATE FUNCTION
statement is issued, SQL Server executes the statement. However, SQL Server does not execute the function when it is
invoked.
The number of times that a function specified in a query is actually executed can vary between execution plans built
by the optimizer. An example is a function invoked by a subquery in a WHERE clause. The number of times the
subquery and its function is executed can vary with different access paths chosen by the optimizer.
Valid statements in a function
The types of statements that are valid in a function include:
DECLARE statements can be used to define data variables and cursors that are local to the function.
Assignments of values to objects local to the function, such as using SET to assign values to scalar and table
local variables.
Cursor operations that reference local cursors that are declared, opened, closed, and deallocated in the
function. FETCH statements that return data to the client are not allowed. Only FETCH statements that assign
values to local variables using the INTO clause are allowed.
Control-of-flow statements except TRY...CATCH statements.
SELECT statements containing select lists with expressions that assign values to variables that are local to
the function.
UPDATE, INSERT, and DELETE statements modifying table variables that are local to the function.
EXECUTE statements calling an extended stored procedure.
Built-in system functions
The following nondeterministic built-in functions can be used in Transact-SQL user-defined functions.
CURRENT_TIMESTAMP
@@MAX_CONNECTIONS
GET_TRANSMISSION_STATUS
@@PACK_RECEIVED
GETDATE
@@PACK_SENT
GETUTCDATE
@@PACKET_ERRORS
@@CONNECTIONS
@@TIMETICKS
@@CPU_BUSY
@@TOTAL_ERRORS
@@DBTS
@@TOTAL_READ
@@IDLE
@@TOTAL_WRITE
@@IO_BUSY
The following nondeterministic built-in functions cannot be used in Transact-SQL user-defined functions.
NEWID
RAND
NEWSEQUENTIALID
TEXTPTR
For a list of deterministic and nondeterministic built-in system functions, see Deterministic and Nondeterministic
Functions.
Schema-bound functions
CREATE FUNCTION supports a SCHEMABINDING clause that binds the function to the schema of any objects it
references, such as tables, views, and other user-defined functions. An attempt to alter or drop any object
referenced by a schema-bound function fails.
These conditions must be met before you can specify SCHEMABINDING in CREATE FUNCTION:
All views and user-defined functions referenced by the function must be schema-bound.
All objects referenced by the function must be in the same database as the function. The objects must be
referenced using either one-part or two-part names.
You must have REFERENCES permission on all objects (tables, views, and user-defined functions) referenced
in the function.
You can use ALTER FUNCTION to remove the schema binding. The ALTER FUNCTION statement should
redefine the function without specifying WITH SCHEMABINDING.
Specifying parameters
A user-defined function takes zero or more input parameters and returns either a scalar value or a table. A function
can have a maximum of 1024 input parameters. When a parameter of the function has a default value, the keyword
DEFAULT must be specified when calling the function to get the default value. This behavior is different from
parameters with default values in user-defined stored procedures in which omitting the parameter also implies the
default value. User-defined functions do not support output parameters.
More examples!
Task Description
Topic
Describes how to create a Transact-SQL user-defined function.
Create User-defined Functions (Database Engine)
Describes how create a CLR function.
Create CLR Functions
Describes how to create a user-defined aggregate function
Create User-defined Aggregates
Describes how to modify a Transact-SQL user-defined
function.
Modify User-defined Functions
Describes how to delete a user-defined function.
Delete User-defined Functions
Describes how to execute a user-defined function.
Execute User-defined Functions
Describes how to rename a user-defined function
Rename User-defined Functions
Describes how to view the definition of a user-defined
function.
View User-defined Functions
Deterministic and Nondeterministic Functions
3/24/2017 • 4 min to read • Edit Online
Deterministic functions always return the same result any time they are called with a specific set of input values
and given the same state of the database. Nondeterministic functions may return different results each time they
are called with a specific set of input values even if the database state that they access remains the same. For
example, the function AVG always returns the same result given the qualifications stated above, but the GETDATE
function, which returns the current datetime value, always returns a different result.
There are several properties of user-defined functions that determine the ability of the SQL Server Database Engine
to index the results of the function, either through indexes on computed columns that call the function, or through
indexed views that reference the function. The determinism of a function is one such property. For example, a
clustered index cannot be created on a view if the view references any nondeterministic functions. For more
information about the properties of functions, including determinism, see User-Defined Functions.
This topic identifies the determinism of built-in system functions and the effect on the deterministic property of
user-defined functions when it contains a call to extended stored procedures.
Built-in Function Determinism
You cannot influence the determinism of any built-in function. Each built-in function is deterministic or
nondeterministic based on how the function is implemented by SQL Server. For example, specifying an ORDER BY
clause in a query does not change the determinism of a function that used in that query.
All of the string built-in functions are deterministic. For a list of these functions, see String Functions (TransactSQL).
The following built-in functions from categories of built-in functions other than string functions are always
deterministic.
ABS
DATEDIFF
POWER
ACOS
DAY
RADIANS
ASIN
DEGREES
ROUND
ATAN
EXP
SIGN
ATN2
FLOOR
SIN
CEILING
ISNULL
SQUARE
COALESCE
ISNUMERIC
SQRT
COS
LOG
TAN
COT
LOG10
YEAR
DATALENGTH
MONTH
DATEADD
NULLIF
The following functions are not always deterministic, but can be used in indexed views or indexes on computed
columns when they are specified in a deterministic manner.
FUNCTION
COMMENTS
all aggregate functions
All aggregate functions are deterministic unless they are
specified with the OVER and ORDER BY clauses. For a list of
these functions, see Aggregate Functions (Transact-SQL).
CAST
Deterministic unless used with datetime, smalldatetime, or
sql_variant.
CONVERT
Deterministic unless one of these conditions exists:
Source type is sql_variant.
Target type is sql_variant and its source type is
nondeterministic.
Source or target type is datetime or smalldatetime, the
other source or target type is a character string, and a
nondeterministic style is specified. To be deterministic, the
style parameter must be a constant. Additionally, styles less
than or equal to 100 are nondeterministic, except for styles 20
and 21. Styles greater than 100 are deterministic, except for
styles 106, 107, 109 and 113.
CHECKSUM
Deterministic, with the exception of CHECKSUM(*).
ISDATE
Deterministic only if used with the CONVERT function, the
CONVERT style parameter is specified and style is not equal to
0, 100, 9, or 109.
RAND
RAND is deterministic only when a seed parameter is specified.
All the configuration, cursor, metadata, security, and system statistical functions are nondeterministic. For a list of
these functions, see Configuration Functions (Transact-SQL), Cursor Functions (Transact-SQL), Metadata Functions
(Transact-SQL), Security Functions (Transact-SQL), and System Statistical Functions (Transact-SQL).
The following built-in functions from other categories are always nondeterministic.
@@CONNECTIONS
GETDATE
@@CPU_BUSY
GETUTCDATE
@@DBTS
GET_TRANSMISSION_STATUS
@@IDLE
LAG
@@IO_BUSY
LAST_VALUE
@@MAX_CONNECTIONS
LEAD
@@PACK_RECEIVED
MIN_ACTIVE_ROWVERSION
@@PACK_SENT
NEWID
@@PACKET_ERRORS
NEWSEQUENTIALID
@@TIMETICKS
NEXT VALUE FOR
@@TOTAL_ERRORS
NTILE
@@TOTAL_READ
PARSENAME
@@TOTAL_WRITE
PERCENTILE_CONT
AT TIME ZONE
PERCENTILE_DISC
CUME_DIST
PERCENT_RANK
CURRENT_TIMESTAMP
RAND
DENSE_RANK
RANK
FIRST_VALUE
ROW_NUMBER
TEXTPTR
Calling Extended Stored Procedures from Functions
Functions that call extended stored procedures are nondeterministic, because the extended stored procedures can
cause side effects on the database. Side effects are changes to a global state of the database, such as an update to a
table, or to an external resource, such as a file or the network; for example, modifying a file or sending an e-mail
message. You should not rely on returning a consistent result set when executing an extended stored procedure
from a user-defined function. User-defined functions that create side effects on the database are not
recommended.
When called from inside a function, the extended stored procedure cannot return result sets to the client. Any Open
Data Services API that returns result sets to the client will have a return code of FAIL.
The extended stored procedure can connect back to SQL Server. However, the procedure cannot join the same
transaction as the original function that invoked the extended stored procedure.
Similar to invocations from a batch or stored procedure, the extended stored procedure is executed in the context
of the Microsoft Windows security account under which SQL Server is running. The owner of the extended stored
procedure should consider this when granting permissions to other users to execute the procedure.
Create User-defined Functions (Database Engine)
3/24/2017 • 3 min to read • Edit Online
This topic describes how to create a user-defined function (UDF) in SQL Server by using Transact-SQL.
Before You Begin
Limitations and restrictions
User-defined functions cannot be used to perform actions that modify the database state.
User-defined functions cannot contain an OUTPUT INTO clause that has a table as its target.
User-defined functions can not return multiple result sets. Use a stored procedure if you need to return
multiple result sets.
Error handling is restricted in a user-defined function. A UDF does not support TRY…CATCH, @ERROR or
RAISERROR.
User-defined functions cannot call a stored procedure, but can call an extended stored procedure.
User-defined functions cannot make use of dynamic SQL or temp tables. Table variables are allowed.
SET statements are not allowed in a user-defined function.
The FOR XML clause is not allowed
User-defined functions can be nested; that is, one user-defined function can call another. The nesting level is
incremented when the called function starts execution, and decremented when the called function finishes
execution. User-defined functions can be nested up to 32 levels. Exceeding the maximum levels of nesting
causes the whole calling function chain to fail. Any reference to managed code from a Transact-SQL userdefined function counts as one level against the 32-level nesting limit. Methods invoked from within
managed code do not count against this limit.
The following Service Broker statements cannot be included in the definition of a Transact-SQL userdefined function:
BEGIN DIALOG CONVERSATION
END CONVERSATION
GET CONVERSATION GROUP
MOVE CONVERSATION
RECEIVE
SEND
Permissions
Requires CREATE FUNCTION permission in the database and ALTER permission on the schema in which the
function is being created. If the function specifies a user-defined type, requires EXECUTE permission on the type.
Scalar Functions
The following example creates a multistatement scalar function in the AdventureWorks2012 database. The function
takes one input value, a
product in inventory.
ProductID
, and returns a single data value, the aggregated quantity of the specified
IF OBJECT_ID (N'dbo.ufnGetInventoryStock', N'FN') IS NOT NULL
DROP FUNCTION ufnGetInventoryStock;
GO
CREATE FUNCTION dbo.ufnGetInventoryStock(@ProductID int)
RETURNS int
AS
-- Returns the stock level for the product.
BEGIN
DECLARE @ret int;
SELECT @ret = SUM(p.Quantity)
FROM Production.ProductInventory p
WHERE p.ProductID = @ProductID
AND p.LocationID = '6';
IF (@ret IS NULL)
SET @ret = 0;
RETURN @ret;
END;
GO
The following example uses the ufnGetInventoryStock function to return the current inventory quantity for
products that have a ProductModelID between 75 and 80.
SELECT ProductModelID, Name, dbo.ufnGetInventoryStock(ProductID)AS CurrentSupply
FROM Production.Product
WHERE ProductModelID BETWEEN 75 and 80;
Table-Valued Functions
The following example creates an inline table-valued function in the AdventureWorks2012 database. The function
takes one input parameter, a customer (store) ID, and returns the columns ProductID , Name , and the aggregate of
year-to-date sales as YTD Total for each product sold to the store.
IF OBJECT_ID (N'Sales.ufn_SalesByStore', N'IF') IS NOT NULL
DROP FUNCTION Sales.ufn_SalesByStore;
GO
CREATE FUNCTION Sales.ufn_SalesByStore (@storeid int)
RETURNS TABLE
AS
RETURN
(
SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS 'Total'
FROM Production.Product AS P
JOIN Sales.SalesOrderDetail AS SD ON SD.ProductID = P.ProductID
JOIN Sales.SalesOrderHeader AS SH ON SH.SalesOrderID = SD.SalesOrderID
JOIN Sales.Customer AS C ON SH.CustomerID = C.CustomerID
WHERE C.StoreID = @storeid
GROUP BY P.ProductID, P.Name
);
The following example invokes the function and specifies customer ID 602.
SELECT * FROM Sales.ufn_SalesByStore (602);
The following example creates a table-valued function in the AdventureWorks2012 database. The function takes a
single input parameter, an EmployeeID and returns a list of all the employees who report to the specified employee
directly or indirectly. The function is then invoked specifying employee ID 109.
IF OBJECT_ID (N'dbo.ufn_FindReports', N'TF') IS NOT NULL
DROP FUNCTION dbo.ufn_FindReports;
GO
CREATE FUNCTION dbo.ufn_FindReports (@InEmpID INTEGER)
RETURNS @retFindReports TABLE
(
EmployeeID int primary key NOT NULL,
FirstName nvarchar(255) NOT NULL,
LastName nvarchar(255) NOT NULL,
JobTitle nvarchar(50) NOT NULL,
RecursionLevel int NOT NULL
)
--Returns a result set that lists all the employees who report to the
--specific employee directly or indirectly.*/
AS
BEGIN
WITH EMP_cte(EmployeeID, OrganizationNode, FirstName, LastName, JobTitle, RecursionLevel) -- CTE name and
columns
AS (
SELECT e.BusinessEntityID, e.OrganizationNode, p.FirstName, p.LastName, e.JobTitle, 0 -- Get the
initial list of Employees for Manager n
FROM HumanResources.Employee e
INNER JOIN Person.Person p
ON p.BusinessEntityID = e.BusinessEntityID
WHERE e.BusinessEntityID = @InEmpID
UNION ALL
SELECT e.BusinessEntityID, e.OrganizationNode, p.FirstName, p.LastName, e.JobTitle, RecursionLevel + 1
-- Join recursive member to anchor
FROM HumanResources.Employee e
INNER JOIN EMP_cte
ON e.OrganizationNode.GetAncestor(1) = EMP_cte.OrganizationNode
INNER JOIN Person.Person p
ON p.BusinessEntityID = e.BusinessEntityID
)
-- copy the required columns to the result of the function
INSERT @retFindReports
SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel
FROM EMP_cte
RETURN
END;
GO
-- Example invocation
SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel
FROM dbo.ufn_FindReports(1);
More examples
User-Defined Functions
CREATE FUNCTION (Transact-SQL)
Alter Function (Transact SQL)
Drop Function (Transact SQL)
Drop Partition Function (Transact SQL)
More examples in the community
Create CLR Functions
3/24/2017 • 2 min to read • Edit Online
THIS TOPIC APPLIES TO:
SQL Server (starting with 2016)
Warehouse
Parallel Data Warehouse
Azure SQL Database
Azure SQL Data
You can create a database object inside an instance of SQL Server that is programmed in an assembly created in
the Microsoft .NET Framework common language runtime (CLR). Database objects that can leverage the rich
programming model provided by the common language runtime include aggregate functions, functions, stored
procedures, triggers, and types.
Creating a CLR function in SQL Server involves the following steps:
Define the function as a static method of a class in a language supported by the .NET Framework. For more
information about how to program functions in the common language runtime, see CLR User-Defined
Functions. Then, compile the class to build an assembly in the .NET Framework by using the appropriate
language compiler.
Register the assembly in SQL Server by using the CREATE ASSEMBLY statement. For more information
about assemblies in SQL Server, see Assemblies (Database Engine).
Create the function that references the registered assembly by using the CREATE FUNCTION statement.
NOTE
Deploying a SQL Server Project in Microsoft Visual Studio registers an assembly in the database that was specified for the
project. Deploying the project also creates CLR functions in the database for all methods annotated with the SqlFunction
attribute. For more information, see Deploying CLR Database Objects.
NOTE
The ability of SQL Server to execute CLR code is off by default. You can create, alter, and drop database objects that reference
managed code modules, but these references will not execute in SQL Server unless the clr enabled Option is enabled by using
sp_configure (Transact-SQL).
Accessing External Resources
CLR functions can be used to access external resources such as files, network resources, Web Services, other
databases (including remote instances of SQL Server). This can be achieved by using various classes in the .NET
Framework, such as System.IO , System.WebServices , System.Sql , and so on. The assembly that contains such
functions should at least be configured with the EXTERNAL_ACCESS permission set for this purpose. For more
information, see CREATE ASSEMBLY (Transact-SQL). The SQL Client Managed Provider can be used to access
remote instances of SQL Server. However, loopback connections to the originating server are not supported in CLR
functions.
To create, modify, or drop assemblies in SQL Server
CREATE ASSEMBLY (Transact-SQL)
ALTER ASSEMBLY (Transact-SQL)
DROP ASSEMBLY (Transact-SQL)
To create a CLR function
CREATE FUNCTION (Transact-SQL)
Accessing Native Code
CLR functions can be used to access native (unmanaged) code, such as code written in C or C++, via the use of
PInvoke from managed code (see Calling Native Functions from Managed Code for details). This can allow you to
re-use legacy code as CLR UDFs, or write performance-critical UDFs in native code. This requires using an UNSAFE
assembly. See CLR Integration Code Access Security for cautions about use of UNSAFE assemblies.
See Also
Create User-defined Functions (Database Engine)
Create User-defined Aggregates
Execute User-defined Functions
View User-defined Functions
Common Language Runtime (CLR) Integration Programming Concepts
Create User-defined Aggregates
3/24/2017 • 1 min to read • Edit Online
You can create a database object inside SQL Server that is programmed in a CLR assembly. Database objects that
can leverage the rich programming model provided by the CLR include triggers, stored procedures, functions,
aggregate functions, and types.
Like the built-in aggregate functions provided in Transact-SQL, user-defined aggregate functions perform a
calculation on a set of values and return a single value.
Creating a user-defined aggregate function in SQL Server involves the following steps:
Define the user-defined aggregate function as a class in a Microsoft .NET Framework-supported language.
For more information about how to program user-defined aggregates in the CLR, see CLR User-Defined
Aggregates. Compile this class to build a CLR assembly using the appropriate language compiler.
Register the assembly in SQL Server using the CREATE ASSEMBLY statement. For more information about
assemblies in SQL Server, see Assemblies (Database Engine).
Create the user-defined aggregate that references the registered assembly using the CREATE AGGREGATE
statement.
NOTE
Deploying a SQL Server Project in Microsoft Visual Studio registers an assembly in the database that was specified for the
project. Deploying the project also creates a user-defined aggregate in the database for all class definitions annotated with
the SqlUserDefinedAggregate attribute. For more information, see Deploying CLR Database Objects.
NOTE
The ability of SQL Server to execute CLR code is off by default. You can create, alter and drop database objects that reference
managed code modules, but these references will not execute in SQL Server unless the clr enabled Option is enabled using
sp_configure (Transact-SQL).
To create, modify, or drop an assembly
CREATE ASSEMBLY (Transact-SQL)
ALTER ASSEMBLY (Transact-SQL)
DROP ASSEMBLY (Transact-SQL)
To create a user-defined aggregate
CREATE AGGREGATE (Transact-SQL)
See Also
Common Language Runtime (CLR) Integration Programming Concepts
Modify User-defined Functions
3/24/2017 • 2 min to read • Edit Online
You can modify user-defined functions in SQL Server 2016 by using SQL Server Management Studio or TransactSQL. Modifying user-defined functions as described below will not change the functions’ permissions, nor will it
affect any dependent functions, stored procedures, or triggers.
In This Topic
Before you begin:
Limitations and Restrictions
Security
To modify a user-defined function, using:
SQL Server Management Studio
Transact-SQL
Before You Begin
Limitations and Restrictions
ALTER FUNCTION cannot be used to perform any of the following actions:
Change a scalar-valued function to a table-valued function, or vice versa.
Change an inline function to a multistatement function, or vice versa.
Change a Transact-SQL function to a CLR function, or vice-versa.
Security
Permissions
Requires ALTER permission on the function or on the schema. If the function specifies a user-defined type, requires
EXECUTE permission on the type.
Using SQL Server Management Studio
To modify a user-defined function
1. Click on the plus sign next to the database that contains the function you wish to modify.
2. Click on the plus sign next to the Programmability folder.
3. Click the plus sign next to the folder that contains the function you wish to modify:
Table-valued Function
Scalar-valued Function
Aggregate Function
4. Right-click the function you want to modify and select Modify.
5. In the Query Window, make the necessary changes to the ALTER FUNCTION statement.
6. On the File menu, click Savefunction_name.
Using Transact-SQL
To modify a user-defined function
1. In Object Explorer, connect to an instance of Database Engine.
2. On the Standard bar, click New Query.
3. Copy and paste the following example into the query window and click Execute.
-- Scalar-Valued Function
USE [AdventureWorks2012]
GO
ALTER FUNCTION [dbo].[ufnGetAccountingEndDate]()
RETURNS [datetime]
AS
BEGIN
RETURN DATEADD(millisecond, -2, CONVERT(datetime, '20040701', 112));
END;
-- Table-Valued Function
USE [AdventureWorks2012]
GO
ALTER FUNCTION [dbo].[ufnGetContactInformation](@PersonID int)
RETURNS @retContactInformation TABLE
(
-- Columns returned by the function
[PersonID] int NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[JobTitle] [nvarchar](50) NULL,
[BusinessEntityType] [nvarchar](50) NULL
)
AS
-- Returns the first name, last name, job title and business entity type for the specified contact.
-- Since a contact can serve multiple roles, more than one row may be returned.
BEGIN
IF @PersonID IS NOT NULL
BEGIN
IF EXISTS(SELECT * FROM [HumanResources].[Employee] e
WHERE e.[BusinessEntityID] = @PersonID)
INSERT INTO @retContactInformation
SELECT @PersonID, p.FirstName, p.LastName, e.[JobTitle], 'Employee'
FROM [HumanResources].[Employee] AS e
INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] = e.[BusinessEntityID]
WHERE e.[BusinessEntityID] = @PersonID;
IF EXISTS(SELECT * FROM [Purchasing].[Vendor] AS v
INNER JOIN [Person].[BusinessEntityContact] bec ON bec.[BusinessEntityID] = v.[BusinessEntityID]
WHERE bec.[PersonID] = @PersonID)
INSERT INTO @retContactInformation
SELECT @PersonID, p.FirstName, p.LastName, ct.[Name], 'Vendor Contact'
FROM [Purchasing].[Vendor] AS v
INNER JOIN [Person].[BusinessEntityContact] bec ON bec.[BusinessEntityID] = v.
[BusinessEntityID]
INNER JOIN [Person].ContactType ct ON ct.[ContactTypeID] = bec.[ContactTypeID]
INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] = bec.[PersonID]
WHERE bec.[PersonID] = @PersonID;
IF EXISTS(SELECT * FROM [Sales].[Store] AS s
INNER JOIN [Person].[BusinessEntityContact] bec ON bec.[BusinessEntityID] = s.[BusinessEntityID]
WHERE bec.[PersonID] = @PersonID)
INSERT INTO @retContactInformation
SELECT @PersonID, p.FirstName, p.LastName, ct.[Name], 'Store Contact'
FROM [Sales].[Store] AS s
INNER JOIN [Person].[BusinessEntityContact] bec ON bec.[BusinessEntityID] = s.
[BusinessEntityID]
INNER JOIN [Person].ContactType ct ON ct.[ContactTypeID] = bec.[ContactTypeID]
INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] = bec.[PersonID]
WHERE bec.[PersonID] = @PersonID;
IF EXISTS(SELECT * FROM [Person].[Person] AS p
INNER JOIN [Sales].[Customer] AS c ON c.[PersonID] = p.[BusinessEntityID]
WHERE p.[BusinessEntityID] = @PersonID AND c.[StoreID] IS NULL)
INSERT INTO @retContactInformation
SELECT @PersonID, p.FirstName, p.LastName, NULL, 'Consumer'
FROM [Person].[Person] AS p
INNER JOIN [Sales].[Customer] AS c ON c.[PersonID] = p.[BusinessEntityID]
WHERE p.[BusinessEntityID] = @PersonID AND c.[StoreID] IS NULL;
END
RETURN;
END;
For more information, see ALTER FUNCTION (Transact-SQL).
Delete User-defined Functions
3/24/2017 • 1 min to read • Edit Online
You can delete (drop) user-defined functions in SQL Server 2016 by using SQL Server Management Studio or
Transact-SQL
In This Topic
Before you begin:
Limitations and Restrictions
Security
To delete a user-defined function, using:
SQL Server Management Studio
Transact-SQL
Before You Begin
Limitations and Restrictions
You will not be able to delete the function if there are Transact-SQL functions or views in the database that
reference this function and were created by using SCHEMABINDING, or if there are computed columns,
CHECK constraints, or DEFAULT constraints that reference the function.
You will not be able to delete the function if there are computed columns that reference this function and
have been indexed.
Security
Permissions
Requires ALTER permission on the schema to which the function belongs, or CONTROL permission on the function.
Using SQL Server Management Studio
To delete a user-defined function
1. Click on the plus sign next to the database that contains the function you wish to modify.
2. Click on the plus sign next to the Programmability folder.
3. Click the plus sign next to the folder that contains the function you wish to modify:
Table-valued Function
Scalar-valued Function
Aggregate Function
4. Right-click the function you want to delete and select Delete.
5. In the Delete Object dialog box, click OK.
IMPORTANT
Click Show Dependencies in the Delete Object dialog box to open the function_nameDependencies dialog box.
This will show all of the objects that depend on the function and all of the objects on which the function depends.
Using Transact-SQL
To delete a user-defined function
1. In Object Explorer, connect to an instance of Database Engine.
2. On the Standard bar, click New Query.
3. Copy and paste the following example into the query window and click Execute.
-- creates function called “Sales.ufn_SalesByStore”
USE AdventureWorks2012;
GO
CREATE FUNCTION Sales.ufn_SalesByStore (@storeid int)
RETURNS TABLE
AS
RETURN
(
SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS 'Total'
FROM Production.Product AS P
JOIN Sales.SalesOrderDetail AS SD ON SD.ProductID = P.ProductID
JOIN Sales.SalesOrderHeader AS SH ON SH.SalesOrderID = SD.SalesOrderID
JOIN Sales.Customer AS C ON SH.CustomerID = C.CustomerID
WHERE C.StoreID = @storeid
GROUP BY P.ProductID, P.Name
);
GO
USE AdventureWorks2012;
GO
-- determines if function exists in database
IF OBJECT_ID (N'Sales.fn_SalesByStore', N'IF') IS NOT NULL
-- deletes function
DROP FUNCTION Sales.fn_SalesByStore;
GO
For more information, see DROP FUNCTION (Transact-SQL).
Execute User-defined Functions
3/24/2017 • 1 min to read • Edit Online
Execute a user defined function using Transact-SQL.
Note: Visit user defined function and Create Function (Transact SQL for more information about user defined
functions.
Before you begin
Limitations and restrictions
In Transact-SQL, parameters can be supplied either by using value or by using @parameter_name=value. A
parameter is not part of a transaction; therefore, if a parameter is changed in a transaction that is later rolled back,
the value of the parameter does not revert to its previous value. The value returned to the caller is always the value
at the time the module returns.
Security
Permissions are not required to run the EXECUTE statement. However, permissions are required on the securables
referenced within the EXECUTE string. For example, if the string contains an INSERT statement, the caller of the
EXECUTE statement must have INSERT permission on the target table. Permissions are checked at the time
EXECUTE statement is encountered, even if the EXECUTE statement is included within a module. For more
information, see EXECUTE (Transact-SQL)
Using Transact-SQL
Example
This example uses the ufnGetSalesOrderStatusText scalar-valued function that is available in most editions of
AdventureWorks . The purpose of the function is to return a text value for sales status from a given integer. Vary the
example by passing integers 1 through 7 to the \@Status parameter.
USE [AdventureWorks2016CTP3]
GO
-- Declare a variable to return the results of the function.
DECLARE @ret nvarchar(15);
-- Execute the function while passing a value to the @status parameter
EXEC @ret = dbo.ufnGetSalesOrderStatusText
@Status = 5;
-- View the returned value. The Execute and Select statements must be executed at the same time.
SELECT N'Order Status: ' + @ret;
-- Result:
-- Order Status: Shipped
Rename User-defined Functions
3/24/2017 • 1 min to read • Edit Online
You can rename user-defined functions in SQL Server 2016 by using SQL Server Management Studio or TransactSQL.
In This Topic
Before you begin:
Limitations and Restrictions
Security
To rename user-defined functions, using:
SQL Server Management Studio
Transact-SQL
Before You Begin
Limitations and Restrictions
Function names must comply with the rules for identifiers.
Renaming a user-defined function will not change the name of the corresponding object name in the
definition column of the sys.sql_modules catalog view. Therefore, we recommend that you do not rename
this object type. Instead, drop and re-create the stored procedure with its new name.
Changing the name or definition of a user-defined function can cause dependent objects to fail when the
objects are not updated to reflect the changes that have been made to the function.
Security
Permissions
To drop the function, requires either ALTER permission on the schema to which the function belongs or CONTROL
permission on the function. To re-create the function, requires CREATE FUNCTION permission in the database and
ALTER permission on the schema in which the function is being created.
Using SQL Server Management Studio
To rename user-defined functions
1. In Object Explorer, click the plus sign next to the database that contains the function you wish to rename
and then
2. Click the plus sign next to the Programmability folder.
3. Click the plus sign next to the folder that contains the function you wish to rename:
Table-valued Function
Scalar-valued Function
Aggregate Function
4. Right-click the function you wish to rename and select Rename.
5. Enter the function’s new name.
Using Transact-SQL
To rename user-defined functions
This task cannot be performed using Transact-SQL statements. To rename a user-defined function using TransactSQL, you must first delete the existing function and then re-create it with the new name. Ensure that all code and
applications that used the function’s old name now use the new name.
For more information, see CREATE FUNCTION (Transact-SQL) and DROP FUNCTION (Transact-SQL).
See Also
sys.sql_expression_dependencies (Transact-SQL)
View User-defined Functions
View User-defined Functions
3/24/2017 • 3 min to read • Edit Online
You can gain information about the definition or properties of a user-defined function in SQL Server 2016 by
using SQL Server Management Studio or Transact-SQL. You may need to see the definition of the function to
understand how its data is derived from the source tables or to see the data defined by the function.
IMPORTANT
If you change the name of an object referenced by a function, you must modify that function so that its text reflects the new
name. Therefore, before renaming an object, display the dependencies of the object first to determine if any functions are
affected by the proposed change.
In This Topic
Before you begin:
Security
To get information about a function, using:
SQL Server Management Studio
Transact-SQL
Before You Begin
Security
Permissions
Using sys.sql_expression_dependencies to find all the dependencies on a function requires VIEW DEFINITION
permission on the database and SELECT permission on sys.sql_expression_dependencies for the database.
System object definitions, like the ones returned in OBJECT_DEFINITION, are publicly visible.
Using SQL Server Management Studio
To show a user-defined function’s properties
1. In Object Explorer, click the plus sign next to the database that contains the function to which you want to
view the properties, and then click the plus sign to expand the Programmability folder.
2. Click the plus sign to expand the Functions folder.
3. Click the plus sign to expand the folder that contains the function to which you want to view the properties:
Table-valued Function
Scalar-valued Function
Aggregate Function
4. Right-click the function of which you want to view the properties and select Properties.
The following properties appear in the Function Properties – function_name dialog box.
Database
The name of the database containing this function.
Server
The name of the current server instance.
User
The name of the user of this connection.
Created date
Displays the date the function was created.
Execute As
Execution context for the function.
Name
The name of the current function.
Schema
Displays the schema that owns the function.
System object
Indicates whether the function is a system object. Values are True and False.
ANSI NULLs
Indicates if the object was created with the ANSI NULLs option.
Encrypted
Indicates whether the function is encrypted. Values are True and False.
Function Type
The type of user defined function.
Quoted identifier
Indicates if the object was created with the quoted identifier option.
Schema bound
Indicates whether the function is schema-bound. Values are True and False. For information about schemabound functions, see the SCHEMABINDING section of CREATE FUNCTION (Transact-SQL).
Using Transact-SQL
To get the definition and properties of a function
1. In Object Explorer, connect to an instance of Database Engine.
2. On the Standard bar, click New Query.
3. Copy and paste one of the following examples into the query window and click Execute.
USE AdventureWorks2012;
GO
-- Get the function name, definition, and relevant properties
SELECT sm.object_id,
OBJECT_NAME(sm.object_id) AS object_name,
o.type,
o.type_desc,
sm.definition,
sm.uses_ansi_nulls,
sm.uses_quoted_identifier,
sm.is_schema_bound,
sm.execute_as_principal_id
-- using the two system tables sys.sql_modules and sys.objects
FROM sys.sql_modules AS sm
JOIN sys.objects AS o ON sm.object_id = o.object_id
-- from the function 'dbo.ufnGetProductDealerPrice'
WHERE sm.object_id = OBJECT_ID('dbo.ufnGetProductDealerPrice')
ORDER BY o.type;
GO
USE AdventureWorks2012;
GO
-- Get the definition of the function dbo.ufnGetProductDealerPrice
SELECT OBJECT_DEFINITION (OBJECT_ID('dbo.ufnGetProductDealerPrice')) AS ObjectDefinition;
GO
For more information, see sys.sql_modules (Transact-SQL) and OBJECT_DEFINITION (Transact-SQL).
To get the dependencies of a function
1. In Object Explorer, connect to an instance of Database Engine.
2. On the Standard bar, click New Query.
3. Copy and paste the following example into the query window and click Execute.
USE AdventureWorks2012;
GO
-- Get all of the dependency information
SELECT OBJECT_NAME(sed.referencing_id) AS referencing_entity_name,
o.type_desc AS referencing_desciption,
COALESCE(COL_NAME(sed.referencing_id, sed.referencing_minor_id), '(n/a)') AS referencing_minor_id,
sed.referencing_class_desc, sed.referenced_class_desc,
sed.referenced_server_name, sed.referenced_database_name, sed.referenced_schema_name,
sed.referenced_entity_name,
COALESCE(COL_NAME(sed.referenced_id, sed.referenced_minor_id), '(n/a)') AS referenced_column_name,
sed.is_caller_dependent, sed.is_ambiguous
-- from the two system tables sys.sql_expression_dependencies and sys.object
FROM sys.sql_expression_dependencies AS sed
INNER JOIN sys.objects AS o ON sed.referencing_id = o.object_id
-- on the function dbo.ufnGetProductDealerPrice
WHERE sed.referencing_id = OBJECT_ID('dbo.ufnGetProductDealerPrice');
GO
For more information, see sys.sql_expression_dependencies (Transact-SQL) and sys.objects (Transact-SQL).