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!

0 comments:

Post a Comment