Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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).