{"id":7897,"date":"2020-02-10T17:45:33","date_gmt":"2020-02-11T00:45:33","guid":{"rendered":"https:\/\/database.guide\/?p=7897"},"modified":"2024-09-21T05:01:26","modified_gmt":"2024-09-20T19:01:26","slug":"create-a-scalar-user-defined-function-in-sql-server","status":"publish","type":"post","link":"https:\/\/database.guide\/create-a-scalar-user-defined-function-in-sql-server\/","title":{"rendered":"Create a Scalar User-Defined Function in SQL Server"},"content":{"rendered":"\n<p class=\"\">In <a href=\"https:\/\/database.guide\/what-is-sql-server\/\">SQL Server<\/a>, you can create a <a href=\"https:\/\/database.guide\/what-is-a-scalar-udf-in-sql-server\/\">scalar user-defined function<\/a> using the <code>CREATE FUNCTION<\/code> statement. A scalar user-defined function, otherwise known as a scalar UDF, is a user-defined function that returns a single value.<\/p>\n\n\n\n<p class=\"\">This article contains examples of creating some basic <a href=\"https:\/\/database.guide\/what-is-t-sql\/\">T-SQL<\/a> scalar UDFs.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Syntax<\/h2>\n\n\n\n<p class=\"\">First, let&#8217;s look at the syntax for creating scalar UDFs.<\/p>\n\n\n\n<p class=\"\">The syntax for T-SQL scalar UDFs goes like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> \nCREATE &#91; OR ALTER ] FUNCTION &#91; schema_name. ] function_name   \n( &#91; { @parameter_name &#91; AS ]&#91; type_schema_name. ] parameter_data_type   \n    &#91; = default ] &#91; READONLY ] }   \n    &#91; ,...n ]  \n  ]  \n)  \nRETURNS return_data_type  \n    &#91; WITH &lt;function_option> &#91; ,...n ] ]  \n    &#91; AS ]  \n    BEGIN   \n        function_body   \n        RETURN scalar_expression  \n    END  \n&#91; ; ]<\/code><\/pre>\n\n\n\n<p class=\"\">And the syntax for CLR scalar UDFs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> \nCREATE &#91; OR ALTER ] FUNCTION &#91; schema_name. ] function_name   \n( { @parameter_name &#91;AS] &#91; type_schema_name. ] parameter_data_type   \n    &#91; = default ] }   \n    &#91; ,...n ]  \n)  \nRETURNS { return_data_type }  \n    &#91; WITH &lt;clr_function_option> &#91; ,...n ] ]  \n    &#91; AS ] EXTERNAL NAME   \n&#91; ; ]  <\/code><\/pre>\n\n\n\n<p class=\"\">The parts at <code>&lt;function_option><\/code> for T-SQL functions and <code>&lt;clr_function_option><\/code> for CLR functions allow you to specify options for the UDF. Function options include adding encryption, <a href=\"https:\/\/database.guide\/what-does-schema-bound-mean-in-sql-server\/\" data-type=\"post\" data-id=\"40165\">schema binding<\/a>, an <code>EXECUTE AS<\/code> clause, as well as specifying what to do when a NULL value is passed as an argument.<\/p>\n\n\n\n<p class=\"\">A full list of arguments and function options can be found on the <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/t-sql\/statements\/create-function-transact-sql?view=sql-server-ver15#arguments\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft website<\/a>.<\/p>\n\n\n\n<p class=\"\">The Microsoft documentation contains a lot of detail, so the following examples are aimed at providing a quick overview of some common concepts and options when creating scalar UDFs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example 1 &#8211; Basic Scalar UDF<\/h2>\n\n\n\n<p class=\"\">Here&#8217;s an example the code used to create a basic T-SQL scalar UDF.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE FUNCTION dbo.ufn_discountPrice( \n    @price DECIMAL(12,2), \n    @discount DECIMAL(12,2) \n    ) \nRETURNS DECIMAL (12,2)\nAS\nBEGIN\n  RETURN @price * (1 - @discount);\nEND;<\/code><\/pre>\n\n\n\n<p class=\"\">This scalar UDF accepts two parameters; <code>@price<\/code> and <code>@discount<\/code>. These are passed in to the function as arguments whenever the function is invoked. The function takes the value of those arguments, performs a calculation using those values, then returns the resulting value. In this case, the discounted price is returned.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example 2 &#8211; Invoke the UDF<\/h2>\n\n\n\n<p class=\"\">Once the UDF has been created, it can then be invoked within T-SQL code any time you need it.<\/p>\n\n\n\n<p class=\"\">Here&#8217;s an example of invoking the UDF:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT dbo.ufn_discountPrice(100, .2) AS Result;<\/code><\/pre>\n\n\n\n<p class=\"\">Result<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">+----------+<br>| Result   |<br>|----------|<br>| 80.00    |<br>+----------+<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example 3 &#8211; Querying a Table<\/h2>\n\n\n\n<p class=\"\">Scalar UDFs can also do stuff like query database tables.<\/p>\n\n\n\n<p class=\"\">Here&#8217;s one that returns the number of albums are in the database for a given artist.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  \nRETURNS smallint\nAS  \nBEGIN  \n    DECLARE @AlbumCount int;\n    SELECT @AlbumCount = COUNT(AlbumId)\n    FROM Albums\n    WHERE ArtistId = @ArtistId; \n    RETURN @AlbumCount;\nEND;<\/code><\/pre>\n\n\n\n<p class=\"\">This is a scalar function because it returns a single value. If we wanted to return a list of albums, then we&#8217;d need to use a <a href=\"https:\/\/database.guide\/what-is-a-table-valued-function-in-sql-server\/\" target=\"_blank\" rel=\"noopener noreferrer\">table-valued function<\/a>, because table-valued functions return its results as a set of rows.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example 4 &#8211; Schema Binding<\/h2>\n\n\n\n<p class=\"\">When you create a user-defined function that depends on other objects in the database, it&#8217;s usually a good idea to schema bind the UDF. Schema binding the UDF ensures that no changes can be done to the underlying objects that could potentially impact the function.<\/p>\n\n\n\n<p class=\"\">For example, you wouldn&#8217;t be able to drop a table that a schema bound UDF uses in its definition.<\/p>\n\n\n\n<p class=\"\">To schema bind a UDF, use <code>WITH SCHEMABINDING<\/code> in its definition. You also need to use two-part names for any objects that are referenced in the UDF.<\/p>\n\n\n\n<p class=\"\">Here&#8217;s the previous example rewritten so that it&#8217;s schema bound:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  \nRETURNS smallint\nWITH SCHEMABINDING\nAS  \nBEGIN  \n    DECLARE @AlbumCount int;\n    SELECT @AlbumCount = COUNT(AlbumId)\n    FROM dbo.Albums\n    WHERE ArtistId = @ArtistId; \n    RETURN @AlbumCount;\nEND;<\/code><\/pre>\n\n\n\n<p class=\"\">So, I changed two things from the first example. I added <code>WITH SCHEMABINDING<\/code>, and I changed <code>Albums<\/code> to <code>dbo.Albums<\/code>.<\/p>\n\n\n\n<p class=\"\">Now if someone tries to drop that table or make other changes to it, they&#8217;ll get an error.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example 5 &#8211; Encryption<\/h2>\n\n\n\n<p class=\"\">You can also use <code>WITH ENCRYPTION<\/code> to encrypt the function.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  \nRETURNS smallint\nWITH ENCRYPTION\nAS  \nBEGIN  \n    DECLARE @AlbumCount int;\n    SELECT @AlbumCount = COUNT(AlbumId)\n    FROM dbo.Albums\n    WHERE ArtistId = @ArtistId; \n    RETURN @AlbumCount;\nEND;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example 6 &#8211; NULL Input<\/h2>\n\n\n\n<p class=\"\">When invoking the function, if any of the arguments is NULL, the function&#8217;s body is still executed. That is, unless you&#8217;ve explicitly stated <code>RETURNS NULL ON NULL INPUT<\/code> in the function&#8217;s definition.<\/p>\n\n\n\n<p class=\"\">Specifying that option will return NULL if any of the arguments are NULL.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  \nRETURNS smallint\nWITH RETURNS NULL ON NULL INPUT\nAS  \nBEGIN  \n    DECLARE @AlbumCount int;\n    SELECT @AlbumCount = COUNT(AlbumId)\n    FROM dbo.Albums\n    WHERE ArtistId = @ArtistId; \n    RETURN @AlbumCount;\nEND;<\/code><\/pre>\n\n\n\n<p class=\"\">When I invoke the function using NULL as the argument:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SELECT dbo.ufn_CountAlbums(NULL) AS Result;<\/pre>\n\n\n\n<p class=\"\">I get a different result, depending on what I&#8217;ve specified for this option.<\/p>\n\n\n\n<p class=\"\">Here&#8217;s the result when the function uses the default setting (<code>CALLED ON NULL INPUT<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">+----------+<br>| Result   |<br>|----------|<br>| 0        |<br>+----------+<\/pre>\n\n\n\n<p class=\"\">And here&#8217;s the result when it uses <code>RETURNS NULL ON NULL INPUT<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">+----------+<br>| Result   |<br>|----------|<br>| NULL     |<br>+----------+<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example 7 &#8211; Multiple Options<\/h2>\n\n\n\n<p class=\"\">You can separate multiple options with a comma.<\/p>\n\n\n\n<p class=\"\">Here&#8217;s an example that adds both encryption and schema binding to the function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  \nRETURNS smallint\nWITH ENCRYPTION, SCHEMABINDING\nAS  \nBEGIN  \n    DECLARE @AlbumCount int;\n    SELECT @AlbumCount = COUNT(AlbumId)\n    FROM dbo.Albums\n    WHERE ArtistId = @ArtistId; \n    RETURN @AlbumCount;\nEND;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example 8 &#8211; Alter a Function<\/h2>\n\n\n\n<p class=\"\">You can alter a scalar UDF by replacing <code>CREATE<\/code> with <code>ALTER<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ALTER FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  \nRETURNS smallint\nWITH SCHEMABINDING\nAS  \nBEGIN  \n    DECLARE @AlbumCount int;\n    SELECT @AlbumCount = COUNT(AlbumId)\n    FROM dbo.Albums\n    WHERE ArtistId = @ArtistId; \n    RETURN @AlbumCount;\nEND;<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In SQL Server, you can create a scalar user-defined function using the CREATE FUNCTION statement. A scalar user-defined function, otherwise known as a scalar UDF, is a user-defined function that returns a single value. This article contains examples of creating some basic T-SQL scalar UDFs.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,5],"tags":[93,77,61,99],"class_list":["post-7897","post","type-post","status-publish","format-standard","hentry","category-sql","category-sql-server","tag-functions","tag-mssql","tag-t-sql","tag-udf"],"_links":{"self":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/7897","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/comments?post=7897"}],"version-history":[{"count":4,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/7897\/revisions"}],"predecessor-version":[{"id":40331,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/7897\/revisions\/40331"}],"wp:attachment":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/media?parent=7897"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/categories?post=7897"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/tags?post=7897"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}