Web design and hosting, database, cloud and social media solutions that deliver business results
  • Business Solutions
    • Robotic Process Automation
    • Software
    • Database Consultancy Services
      • Data Integration
      • Datawarehouse Services
      • Power BI
      • Server Upgrade and DBA Services
    • Web Site Design Services
      • Logo Design
      • Payment Gateways
      • Web Localisation and Translation
      • Web Site Optimisation
      • Web Site Security
      • Technical Tools
    • Cloud Services
      • Amazon Web Services
      • Google Cloud Services
      • Microsoft Azure
    • Microsoft Office
    • Social Media Management and Advice Services
  • Academy
    • Our Test Environment
    • Learning Databases
      • The Basics
      • Get Open Query
      • SQL Server Data
      • SQL Server Maintenance
      • Using SQL Server Dates
      • Using SQL Server Functions
      • Using SQL Server Pivot-Unpivot
      • Technical Tools
    • Learning Web Design
      • Building Ousia Content Management System
      • Using ASP-NET
      • Using CSS
      • Using JavaScript
    • Learning Cloud and IT Services
      • Task Scheduler Error 2147943645
      • Requesting SSL and Generation of PFX file in OpenSSL Simple Steps
    • Using Social Media
      • Asking for a Google Review
      • Changing a Facebook account from personal to business
      • Choosing where to focus Social Media effort
      • Social Media Image Sizes
      • Using Meta Data to set Social Media Images
  • About Us
    • Blog
      • Building an entry level gaming machine
      • Google Core Update Jan 2020
      • Hot Chilli Internet Closure
      • How To Choose Content For Your Website Adverts Leaflets
      • Preventing Online Scam
      • Skimmers of the gig economy
      • The most annoying things about websites on the Internet
      • Top 5 websites for free Vector Graphics
    • Careers
      • Translator English-Portuguese
      • Translator English-Spanish
    • Portfolio
    • Team
      • Adrian Anandan
      • Ali Al Amine
      • Ayse Hur
      • Chester Copperpot
      • Deepika Bandaru
      • Gavin Clayton
      • Sai Gangu
      • Suneel Kumar
      • Surya Mukkamala
عربى (AR)čeština (CS)Deutsch (DE)English (EN-GB)English (EN-US)Español (ES)فارسی (FA)Français (FR)हिंदी (HI)italiano (IT)日本語 (JA)polski (PL)Português (PT)русский (RU)Türk (TR)中国的 (ZH)

Introduction into SQL Server Functions, their benefits and drawbacks

Any well written database will have a selection of functions, most of the time they are useful but when used in the wrong context they can actually harm performance

What is an SQL Function?

Using SQL Server Functions

SQL Server functions can be used to return either single(scaler) values, or tables, using T-SQL or CLR (common language run-time) routines and often performing more complex calculations than you would want to use in general code.

When is it a good idea to use a function rather than inline code?

Good Use

Functions can be used to replace views (return a table), as a calculated column in a table, perform consistent lookup actions or simply just to modularise your code which can help in reducing changes needed.

Bad Use

We see it all the time, but functions should not be used to return lookup data in place of a join when you are dealing with large datasets. Each row will call the same function even if it has already encountered that value. In these cases, use a join.

Scaler function examples

Scaler functions are best used to perform logic like row based re-formatting or calculations as by their nature they are called for every row, they can be used for looking up data in another table, but in general, you will get better performance by using a join. For this, we can look at our get age function on the following link.

Storing someone’s age at the time they filled out a form would make no sense, as when the data is queried later it will be out of date. A better option would be to capture a date of birth and calculate it on the fly. In our function we added a field until, which can be used to backdate a calculation, or perhaps more sombrely, calculate age a time of death (this function was extended for an NHS contract).

More: Get Age

Example

CREATE FUNCTION [Dates].[GetAge](@Date DATETIME2,@Until DATETIME2) RETURNS INT AS BEGINIF @Until IS NULL SET @Until=CONVERT(DATE,GETDATE())DECLARE @Age INT=DATEDIFF(YEAR,@Date,@Until)+(CASE WHEN DATEPART(DAYOFYEAR,@Date)>(DATEPART(DAYOFYEAR,@Until)+(CASE WHEN dbo.GetLeapYear(@Date)=1 AND DATEPART(DAYOFYEAR,@Date)>59 THEN 1 ELSE 0 END))THEN -1 ELSE 0 END)RETURN @AgeEND

Scaler function examples

To use this from a fictional table we would simply use this, which would provide either current age or age at death.

Use in a select statement

SELECT [PersonID],[DateOfBirth],[dbo].[GetAge]([DateOfBirth],[DeceasedDate]) AgeAsFunction,--Simpler code to understand!DATEDIFF(YEAR,[DateOfBirth],[DeceasedDate])+(CASE WHEN DATEPART(DAYOFYEAR,[DateOfBirth])>(DATEPART(DAYOFYEAR,[DeceasedDate])+(CASE WHEN dbo.GetLeapYear([DateOfBirth])=1 AND DATEPART(DAYOFYEAR,[DateOfBirth])>59 THEN 1 ELSE 0 END))THEN -1 ELSE 0 END) AgeAsScript,[DeceasedDate]FROM [Person]

Scaler function examples

Advantages: Consistent, modular, more compact, potentially reduces number of changes

Disadvantages: To see the code you need to look in the function

While being generally useful, this function is extremely accurate too, because it utilises a leap year function. It is non-deterministic by nature so should never be stored as persisted data.

Table column examples

Calculated columns can be added as either persisted (changes when the data does) or non-persisted (calculated every time the row is selected). We can look at two ways we have used them here within our Content Management System.

Note: Persisted data can be harder to achieve as it requires a set of constraints to be met

Non-persisted: Age

Using the age function as above, we can add this into a table and pass in values from other columns. We then simply select it as a column.

Add to a table

CREATE TABLE [Person]([PersonID] [int] IDENTITY(1,1) NOT NULL,[DateOfBirth] [datetime] NULL,[Age] AS ([dbo].[GetAge]([DateOfBirth],[DeceasedDate])),[DeceasedDate] [datetime] NULL)

Select Statement

SELECT [PersonID],[DateOfBirth],[Age] AgeAsColumn,--Even simpler code to understand!DATEDIFF(YEAR,[DateOfBirth],[DeceasedDate])+(CASE WHEN DATEPART(DAYOFYEAR,[DateOfBirth])>(DATEPART(DAYOFYEAR,[DeceasedDate])+(CASE WHEN dbo.GetLeapYear([DateOfBirth])=1 AND DATEPART(DAYOFYEAR,[DateOfBirth])>59 THEN 1 ELSE 0 END))THEN -1 ELSE 0 END) AgeAsScript,[DeceasedDate]FROM [Person]

Non-persisted: Age

Advantages: Consistent, modular

Disadvantages: Slows query speed if not needed.

Persisted: Minified CSS

We have a function that reduces space needed for CSS by up to 30%. Calling this regularly would slow down the select speed of the table, and as the data is rarely updated it made sense to perform calculations at insert/update time. By creating the column as a function, we have no need to perform these operations as a trigger either.

More: CSS Pre Processor in SQL

Add to a Table

CREATE TABLE CSS(CSSID INT IDENTITY(1,1) NOT NULL,CSSText NVARCHAR(MAX),CSSMin AS (ous.CSSProcessor([CSSText])) PERSISTED)

Persisted: Minified CSS

It can be selected just like a normal column, and data is stored in the table. It also avoids the use of a massive replace statement bloating our code.

Advantages: Consistent, modular, faster select speed, no need for a trigger!

Disadvantages: Increases space needed for table, slows insert speed

Replacing a view

We tend not to use views, apart from when we are regularly using the same joins in multiple places.

Even in these instances, there is no reason why a table function can’t be used more effectively. The table we have used can be found on the link below, and we have two examples of usage, one via a function and the other using a view.

more: Using SQL Server Dates

Create a function

CREATE FUNCTION Dates.GetCalender(@DateFrom DATETIME2,@DateTo DATETIME2,@Function INT) RETURNS @D TABLE (CalenderDate DATETIME2(7) NOT NULL PRIMARY KEY,CalenderCA INT NULL,CalenderCD INT NULL,WeekDayID INT NULL,WeekDayName VARCHAR(9) NULL,HolidayType NVARCHAR(100)) AS BEGININSERT INTO @DSELECT c.*,HolidayTypeFROM [Utilities].[Dates].[Calender] cLEFT JOIN Utilities.Dates.CalenderHolidays h ON h.CalenderDate=c.CalenderDate AND CalenderFunction=@FunctionWHERE c.CalenderDate BETWEEN @DateFrom AND @DateTo RETURNENDGO

Create a view

CREATE VIEW Dates.GetCalenderView ASSELECT c.CalenderDate, CalenderCA, CalenderCD, WeekDayID, WeekDayName,h.HolidayType,c.CalenderFunctionFROM (SELECT CalenderDate, CalenderCA, CalenderCD, WeekDayID, WeekDayName, CalenderFunction FROM [Utilities].[Dates].[Calender],(SELECT DISTINCT CalenderFunction FROM Dates.CalenderHolidays) x) cLEFT JOIN Utilities.Dates.CalenderHolidays h ON h.CalenderDate=c.CalenderDate AND h.CalenderFunction=c.CalenderFunction

Usage

SELECT * FROM Dates.GetCalender('2018-01-01','2018-12-31',0) --England & WalesSELECT * FROM Dates.GetCalender('2018-01-01','2018-12-31',1) --Scotland----OR----SELECT * FROM Dates.GetCalenderView WHERE CalenderDate BETWEEN '2018-01-01' AND '2018-12-31' AND CalenderFunction=0

Replacing a view

Benefits: Compact to call, returned with Primary Key (perfect for further join), parameters could be used earlier in code.

Disadvantages: More code to build, less flexible

Use in Apply Joins

Table functions are great to use in Apply Joins, as data can be passed in on a row-by-row basis. We use our TextToRows function to pull strings apart in SQL Server. In the example below we use a double apply to split the data twice with different delimiters.

more: SQL Server function splitting text into data rows

SQL Code

DECLARE @TestText TABLE(TextToSplit NVARCHAR(100))INSERT INTO @TestText SELECT 'Text,To,Tows:Split,One'INSERT INTO @TestText SELECT 'Text,To,Tows:Split,Two'SELECT t.TextToSplit,s1.WordInt,s1.WordStr,s2.WordInt,s2.WordStrFROM @TestText tOUTER APPLY dbo.TextToRows(':',TextToSplit) s1OUTER APPLY dbo.TextToRows(',',WordStr) s2

Further detail

Some of the functions we have written can be found below.

Adding Text Padding

This simple little function is used all over our various databases, and gives us a nice way of guaranteeing the format of a string.

Calculate the distance between two longitude latitude coordinates

Create an SQL function that calculates the distance between latitude/longitude coordinates in either miles or kilometers, and tested with football club stadiums

Cleansing a UK Telephone Number

Create an SQL Server function to check and cleanse an International or UK based Telephone Number string

Cleansing of UK Address Postcodes

Create an SQL Server Function to cleanse, replace common mistakes and re-format UK Postcodes with the correct space position

Cleansing text strings in keeping letters and numbers

Create a function to cleanse text strings of all characters that are not between 0-9 or A-Z in SQL Server

Concatenating columns

A flexible and re-usable SQL Server Function to return a formatted and delimited text string from a set of columns or variables

Dynamically Generating File Name

How to use SQL Server to dynamically create variable file names, bind it to a table and use the data in a real world example

Min and max value for columns

Creating a function to return the min and max value for columns by concatenating the strings, splitting them into rows and then returning the correct value

Splitting text into data rows

SQL function to separate a string test delimiters from any characters into rows. We use it as a base to execute different functions and add text to tables.
Copyright Claytabase Ltd 2020

Registered in England and Wales 08985867

Site Links

RSSLoginLink Cookie PolicySitemap

Social Media

facebook.com/Claytabaseinstagram.com/claytabase/twitter.com/Claytabaselinkedin.com/company/claytabase-ltd

Get in Touch

+15125961417info@claytabase.comClaytabase USA, 501 Congress Avenue, Suite 150, Austin, Texas, 78701, United States

Partnered With

The settings on this site are set to allow all cookies. These can be changed on our Cookie Policy & Settings page.
By continuing to use this site you agree to the use of cookies.
Ousia Logo
Logout
Ousia CMS Loader