SESSION_CONTEXT in Sql Server 2016

In .Net we have Session object which provides a mechanism to store and retrieve values for a user as user navigates ASP.NET pages in a Web application for that session. With Sql Server 2016 we are getting the similar feature in Sql Server, where we can store multiple key and value pairs which are accessible throughout that session. The key and value pairs can be set by the sp_set_session_context system stored procedure and these set values can be retrieved one at a time by using the SESSION_CONTEXT built in function.

This article explains in detail with extensive list of examples on how we can store the information that can be accessed anywhere in that session.

In this article for the Session Context key value pairs I will be interchangeably referring them as Session Variables. I hope most of the .Net developers too prefer calling them as session variables.

EXAMPLE 1: This example demonstrates how we can set the session context key named EmployeeId with it’s value and retrieving this set keys value.

--Set the session variable EmployeeId value
EXEC sp_set_session_context 'EmployeeId', 5000
--Retrieve the session variable EmployeeId value
SELECT SESSION_CONTEXT(N'EmployeeId') AS EmployeeId

RESULT:
SessionContext Sql Example 1 1

Let us try to re-get the session context key EmployeeId value, but this time while specifying the key EmployeeId parameter skipping the prefix N:

--Retrieve the session variable EmployeeId value
SELECT SESSION_CONTEXT('EmployeeId') AS EmployeeId

RESULT:

Msg 8116, Level 16, State 1, Line 2
Argument data type varchar is invalid for argument 1 of session_context function.

From the result it is clear that the SESSION_CONTEXT function always expects the key parameter passed to it should of type NVarchar.

Let us re-execute the above statement by prefixing the key parameter by N

--Retrieve the session variable EmployeeId value
SELECT SESSION_CONTEXT(N'EmployeeId') AS EmployeeId

RESULT:
SessionContext Sql Example 1 2

EXAMPLE 2: Below example shows how we can update the Session variable value

--Set session variable EmployeeName value
EXEC sp_set_session_context @key = 'EmployeeName', 
  @value='Basavaraj'
--Retrieve the session variable EmployeeName value
SELECT SESSION_CONTEXT(N'EmployeeName') EmployeeName
--Re-Set the EmployeeName session variable value
EXEC sp_set_session_context @key ='EmployeeName',
  @value='Basavaraj Biradar'
--Retrieve the update session variable EmployeeName value
SELECT SESSION_CONTEXT(N'EmployeeName') EmployeeName

RESULT:
updating session context value Example 2

EXAMPLE 3: Below example demonstrates a session variable can be declared as readonly

First create the readonly session variable City by using the following statement. We can mark a session variable as readonly by specying the parameter @read_only value as 1. This parameter is optional, if we don’t specify it or if we specify this parameter value as 0 then Sql Server will not allow to update this value later.

--create a readonly session variable City
EXEC sp_set_session_context @key = 'City', @value='Bangalore', 
  @read_only = 1
--Retrieve the session variable City value
SELECT SESSION_CONTEXT(N'City') City

RESULT:
SessionContext Setting Readonly Variable value Example 3

Now try to update the read-only session variable City value by the following statement

--try to update the read-only City session variable value
EXEC sp_set_session_context @key ='City',@value='Bengaluru'

RESULT:

Msg 15664, Level 16, State 1, Procedure sp_set_session_context, Line 1
Cannot set key ‘City’ in the session context. The key has been set as read_only for this session.

SYNTAX of sp_set_session_context:

sp_set_session_context [ @key= ] 'key', [ @value= ] 'value'
    [ , [ @read_only = ] { 0 | 1 } ]

Where: @key parameter is of type SYSNAME, @value is of type SQL_VARIANT and @read_only parameter is of type BIT

SYNTAX of SESSION_CONTEXT

SESSION_CONTEXT(N'key')

Where:’key’ parameter to this function is of type SYSNAME and the return type of this function is SQL_VARIANT

EXAMPLE 4: Below example demonstrates how a session variable can be accessed in stored procedure which is set somewhere outside.

Let us create a stored procedure GetCountry by the following script:

CREATE PROCEDURE GetCountry
AS
BEGIN
	SELECT SESSION_CONTEXT(N'Country') Country
END

Then by using the following script create the session variable Country

--create a readonly session variable Country
EXEC sp_set_session_context @key = 'Country', @value='India'
--Retrieve the session variable Country value
SELECT SESSION_CONTEXT(N'Country') Country

RESULT:
Session Context Example 4 1

Now in the same session execute the stored procedure GetCountry and see whether this SP has access to the Session variable Country:

EXEC GetCountry

RESULT:
Accessing SessionContext from the Stored Procedure Example 4 2

EXAMPLE 5: Below example demonstrates the behavior when we try to fetch a non-existent session variable

SELECT SESSION_CONTEXT(N'Continent') Continent

RESULT:
Non Existent SessionContext Sql Example 5

From the result it is clear that, NULL value will be returned by SESSION_CONTEXT function if we try to fetch non-existent session variable.

The maximum size of the session context is limited to 256 kb. So there is no specific limit or the number of key and value pairs that can be stored in the Session Context as long as the total size is less than 256 Kb and it raises an error if the total size cross this max size limit. Note this limit of 256 Kb is at session level, so we can have multiple sessions at the same time with each session max limit is 256 kb.

We can check the overall memory usage for the session context across all the session by using the below statement:

SELECT cache_address, name, pages_kb, pages_in_use_kb, 
	entries_count, entries_in_use_count
FROM sys.dm_os_memory_cache_counters 
WHERE TYPE = 'CACHESTORE_SESSION_CONTEXT'

RESULT:
SessionContext Memory Usage Details in Sql Example 6

From the above result we can see that we have two active sql sessions with session context info stored. Out of these two session, the 2nd session is having 200 key value pairs stored in it and it is using 88 kb. And below is the script which is used to generate the 200 key value pairs:

DECLARE @Counter INT = 0,  @KeyName SYSNAME
WHILE @Counter < 200
BEGIN
  SET @KeyName = N'Key' + CAST(@Counter AS NVARCHAR);
  EXEC sys.sp_set_session_context @key = @KeyName, @value = 20
  SET @Counter += 1;
END

[ALSO READ]

Difference between DATEDIFF and DATEDIFF_BIG functions in Sql Server

This article gives an introduction to the DATEDIFF and DATEDIFF_BIG functions by listing out the differences and similarities between them.

[ALSO READ]: How to get difference between two dates in Years, Months and days in Sql Server

DATEDIFF Function DATEDIFF_BIG Function
This function is available from very old versions of Sql Server. This function is introduced in Sql Server 2016
This function returns the number of the specified datepart boundaries crossed between the specified startdate and enddate This function returns the number of the specified datepart boundaries crossed between the specified startdate and enddate
Syntax:
DATEDIFF( datepart, startdate, enddate)

Where datepart can be one of the following values: year, quarter, month, dayofyear, day, week, hour, minute, second, millisecond, microsecond and
nanosecond

Syntax:
DATEDIFF_BIG(datepart,startdate,enddate)

Where datepart can be one of the following values: year, quarter, month, dayofyear, day, week, hour, minute, second, millisecond, microsecond and
nanosecond

This functions return value data type is INT This functions return value data type is BigINT
Example: Below is an example getting difference between two dates in days using DATEDIFF function:

SELECT DATEDIFF(DAY,
 '12/01/2015','12/02/2015')
 AS 'Difference in days'

RESULT:
Difference in days
——————
1

Example: Below is an example getting difference between two dates in days using DATEDIFF_BIG function:

SELECT DATEDIFF_BIG(DAY,
 '12/01/2015','12/02/2015')
  AS 'Difference in days'

RESULT:
Difference in days
——————–
1

Example: This example demonstrates the behavior of the DATEDIFF function when the milliseconds difference between two dates is greater than the INT max (i.e. 2,147,483,647) value.

SELECT DATEDIFF(MILLISECOND,
 '12/01/2015','12/30/2015')
 AS 'Difference in MILLISECOND'

RESULT:

Msg 535, Level 16, State 0, Line 1
The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

Example: This example demonstrates the behavior of the DATEDIFF_BIG function when the milliseconds difference between two dates is greater than the INT max (i.e. 2,147,483,647) value.

SELECT DATEDIFF_BIG(MILLISECOND,
 '12/01/2015','12/30/2015') 
AS 'Difference in MILLISECOND'

RESULT:
Difference in MILLISECOND
————————-
2505600000

The minimum and maximum value that this function can return is: -2,147,483,648 and +2,147,483,647 The minimum and maximum value that this function can return is: -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807

ALSO READ

DATEDIFF_BIG Function in Sql Server 2016

DATEDIFF_BIG is one of the new function introduced in Sql Server 2016. It gives the difference between the two dates in the units specified by the DatePart parameter and the returned unit is of type bigint. This function like DATEDIFF function returns the number of the specified datepart boundaries crossed between the specified startdate and enddate. The difference between these two functions is the return type. DATEDIFF functions return type is INT, whereas the DATEDIFF_BIG functions return type is BIGINT.

Syntax:

DATEDIFF_BIG ( datepart , startdate , enddate )

[ALSO READ] Difference between DATEDIFF and DATEDIFF_BIG functions in Sql Server

The request for this new function was submitted on the Microsoft connect site some time back in 2008 by Erland Sommarskog.

With DATEDIFF function for milliseconds the maximum difference between startdate and enddate is 24 days, 20 hours, 31 minutes and 23.647 seconds. For second, the maximum difference is 68 years. This is because the return type of the DATEDIFF function is INT and INT datatypes Min and Max value is: -2,147,483,648 to +2,147,483,647. But with DATEDIFF_BIG function the maximum difference is very high as the return type is bigint and it’s Min and Max value is: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

Example 1: Basic example

SELECT DATEDIFF_BIG(DAY, GETDATE(), GETDATE()+1) 'DateDiff Big'

RESULT:
DATEDIFF_BIG Basic example

ALSO READ: How to get difference between two dates in Years, Months and days in Sql Server

Example 2: Below example demonstrates how DATEDIFF and DATEDIF_BIG functions behave differently when the milliseconds difference between two dates is greater than the INT max (i.e. 2,147,483,647) value.

SELECT DATEDIFF(ms, '2015-12-01', '2015-12-31') 'DateDiff'

RESULT:

Msg 535, Level 16, State 0, Line 1
The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

SELECT DATEDIFF_BIG(ms, '2015-12-01', '2015-12-31') 'DateDiff' 

RESULT:
DATEDIFF_BIG Sql Example

So, if we know that sometime the difference between two dates is going to cross the INT max value then we have to use the DATEDIFF_BIG function

[ALSO READ]: