Home > Sql Server, T-Sql > Sql Agent Session Storage

Sql Agent Session Storage

I’ve been fiddling around with some jobs recently that required values to be kept from one job step to another. Not finding anything much exciting I went for plan Z – roll my own.

They’re simple procedures but do work nicely.

First I create a Schema that everything will be bundled under:

  1. If Not Exists ( Select 1 From sys.schemas Where Name = 'Aracs.Utilities.Jobs')
  2.     Exec sp_ExecuteSql N'Create Schema [Aracs.Utilities.Jobs]';

 

Now we’ll need a backing store:

  1. Create Table [Aracs.Utilities.Jobs].SessionSaverStore
  2.     (
  3.          JobId                UniqueIdentifier        Not Null
  4.         ,ParameterName        NVarChar(128)            Not Null
  5.         ,Value                Sql_Variant                Null
  6.     );

 

Next I create the SessionDestroyer Procedure (since it can be called from the next one this keeps the dependencies happy and calm):

  1. If Object_Id('[Aracs.Utilities.Jobs].SessionDestroyer') Is Null
  2.     Exec sp_ExecuteSql N'Create Procedure [Aracs.Utilities.Jobs].SessionDestroyer As';
  3.  
  4. Go
  5.  
  6. Alter Procedure [Aracs.Utilities.Jobs].SessionDestroyer
  7.  
  8. As
  9.  
  10.     Declare     @JobHex                    NVarChar(32)    
  11.             ,@JobId                        UniqueIdentifier
  12.     ;
  13.     
  14.     Select    @JobHex = Substring(Program_Name, 32, 32)
  15.       From    sys.dm_Exec_Sessions
  16.       Where    Session_Id = @@Spid;
  17.  
  18.     Delete    [Aracs.Utilities.Jobs].SessionSaverStore
  19.       Where    JobId = Cast('' as xml).value('xs:hexBinary(sql:variable("@JobHex") )', 'VarBinary(MAX)');

 

Along comes the SessionSaverStore next:

  1. If Object_Id('[Aracs.Utilities.Jobs].SessionSaverStore') Is Null
  2.     Create Table [Aracs.Utilities.Jobs].SessionSaverStore
  3.         (
  4.              JobId                        UniqueIdentifier
  5.             ,ParameterName                NVarChar(128)
  6.             ,Value                        Sql_Variant
  7.         );
  8.         
  9. If Object_Id('[Aracs.Utilities.Jobs].SessionSaver') Is Null
  10.     Exec sp_ExecuteSql N'Create Procedure [Aracs.Utilities.Jobs].SessionSaver As';
  11.  
  12. Go
  13.  
  14. Alter Procedure [Aracs.Utilities.Jobs].SessionSaver
  15.              @ParameterName                NVarChar(128)
  16.             ,@Value                        Sql_Variant
  17.             ,@StartFresh                Bit = 0
  18.  
  19. As
  20.  
  21.     Declare     @JobHex                    NVarChar(32)
  22.             ,@JobId                        UniqueIdentifier
  23.     ;
  24.     
  25.     Select    @JobHex = Substring(Program_Name, 32, 32)
  26.       From    sys.dm_Exec_Sessions
  27.       Where    Session_Id = @@Spid;
  28.  
  29.     Set @JobId = Cast('' as xml).value('xs:hexBinary(sql:variable("@JobHex") )', 'VarBinary(MAX)');      
  30.     If Exists ( Select 1 From MSDB.dbo.sysJobs Where Job_Id = @JobId )
  31.     Begin
  32.         If @StartFresh = 1
  33.             Exec [Aracs.Utilities.Jobs].SessionDestroyer;
  34.             
  35.         If Exists (
  36.             Select    1
  37.               From    [Aracs.Utilities.Jobs].SessionSaverStore
  38.               Where JobId = @JobId
  39.                 And ParameterName = @ParameterName
  40.         )
  41.             Update    [Aracs.Utilities.Jobs].SessionSaverStore
  42.               Set    Value = @Value
  43.               Where    JobId = @JobId
  44.                 And    ParameterName = @ParameterName;
  45.         
  46.         Else
  47.             Insert
  48.               Into    [Aracs.Utilities.Jobs].SessionSaverStore
  49.                     (
  50.                          JobId
  51.                         ,ParameterName
  52.                         ,Value
  53.                     )
  54.                 Values
  55.                     (
  56.                          @JobId
  57.                         ,@ParameterName
  58.                         ,@Value
  59.                     );
  60.     End

 

Finally the SessionRetriever:

  1. If Object_Id('[Aracs.Utilities.Jobs].SessionRetriever') Is Null
  2.     Exec sp_ExecuteSql N'Create Procedure [Aracs.Utilities.Jobs].SessionRetriever As';
  3.  
  4. Go
  5.  
  6. Alter Procedure [Aracs.Utilities.Jobs].SessionRetriever
  7.              @ParameterName                NVarChar(128)
  8.             ,@Value                        Sql_Variant        Output
  9. As
  10.  
  11.     Declare     @JobHex                    NVarChar(32)    
  12.             ,@JobId                        UniqueIdentifier
  13.             ,@Valuei                    Sql_Variant
  14.             ,@DataType                    NVarChar(128)
  15.     ;
  16.     
  17.     Select    @JobHex = Substring(Program_Name, 32, 32)
  18.       From    sys.dm_Exec_Sessions
  19.       Where    Session_Id = @@Spid;
  20.  
  21.     Set @JobId = Cast('' as xml).value('xs:hexBinary(sql:variable("@JobHex") )', 'VarBinary(MAX)');      
  22.     If Exists ( Select 1 From MSDB.dbo.sysJobs Where Job_Id = @JobId )
  23.     Begin
  24.         Select    @Value = Value
  25.           From    [Aracs.Utilities.Jobs].SessionSaverStore
  26.           Where    JobId = @JobId
  27.             And    ParameterName = @ParameterName;
  28.  
  29.     End

 

Use is pretty straightforward. As an Proof of concept I created a Sql Agent Job with two steps – Store’ and ‘Fetch’

Store contained the following:

  1. Exec [Aracs.Utilities.Jobs].SessionSaver 'Name', 'Fred', 1
  2. Exec [Aracs.Utilities.Jobs].SessionSaver 'Age', 37

 

And Fetch:

  1. Declare @Name Sql_Variant
  2. Declare @Age Sql_Variant
  3.  
  4.   Exec[Aracs.Utilities.Jobs].SessionRetriever 'Name', @Name Output;
  5.   Exec[Aracs.Utilities.Jobs].SessionRetriever 'Age', @Age Output;
  6.  
  7. Print Cast(@Name As VarChar(128)) + ' ' + Cast( @Age As VarChar(4));

 

Granted it’s missing some bells and whistles (like exception handling) and I’d wager I could stuff the Retriever in as a function. However as a first hit I was pretty chuffed with it!

Advertisement
Categories: Sql Server, T-Sql
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.