Puisque vous utilisez apparemment SQL Server 2016, je voudrais jeter une autre option « possible » - SESSION_CONTEXT
.
L'article de Leonard Lobel, Partage de l'état dans SQL Server 2016 avecSESSION_CONTEXT
contient de très bonnes informations sur cette nouvelle fonctionnalité dans SQL Server 2016.
Résumant certains points clés:
Si vous avez toujours voulu partager l'état de session entre toutes les procédures stockées et les lots tout au long de la durée de vie d'une connexion à une base de données, vous allez adorer SESSION_CONTEXT
. Lorsque vous vous connectez à SQL Server 2016, vous obtenez un dictionnaire avec état, ou ce que l'on appelle souvent un sac d'état, un endroit où vous pouvez stocker des valeurs, comme des chaînes et des nombres, puis les récupérer à l'aide d'une clé que vous attribuez. Dans le cas de SESSION_CONTEXT
, la clé est n'importe quelle chaîne et la valeur est un sql_variant, ce qui signifie qu'elle peut accueillir une variété de types.
Une fois que vous avez stocké quelque chose SESSION_CONTEXT
, il y reste jusqu'à la fermeture de la connexion. Il n'est stocké dans aucune table de la base de données, il vit juste en mémoire tant que la connexion reste active. Et tout et tout code T-SQL qui s'exécute dans des procédures stockées, des déclencheurs, des fonctions ou quoi que ce soit, peut partager tout ce que vous introduisez
SESSION_CONTEXT
.
La chose la plus proche que nous ayons eu jusqu'à présent a été CONTEXT_INFO
, ce qui vous permet de stocker et de partager une seule valeur binaire jusqu'à 128 octets de long, ce qui est beaucoup moins flexible que le dictionnaire que vous obtenez SESSION_CONTEXT
, qui prend en charge plusieurs valeurs de données différentes les types.
SESSION_CONTEXT
est facile à utiliser, il suffit d'appeler sp_set_session_context pour stocker la valeur par une clé souhaitée. Lorsque vous faites cela, vous fournissez la clé et la valeur bien sûr, mais vous pouvez également définir le paramètre read_only sur true. Ceci verrouille la valeur dans le contexte de la session, de sorte qu'elle ne peut pas être modifiée pour le reste de la durée de vie de la connexion. Ainsi, par exemple, il est facile pour une application cliente d'appeler cette procédure stockée pour définir des valeurs de contexte de session juste après avoir établi la connexion à la base de données. Si l'application définit le paramètre read_only lorsqu'elle le fait, les procédures stockées et tout autre code T-SQL qui s'exécute ensuite sur le serveur ne peuvent lire que la valeur, ils ne peuvent pas modifier ce qui a été défini par l'application exécutée sur le client.
À titre de test, j'ai créé un déclencheur de connexion au serveur qui définit certaines CONTEXT_SESSION
informations - l'un des a SESSION_CONTEXT
été défini sur @read_only
.
DROP TRIGGER IF EXISTS [InitializeSessionContext] ON ALL SERVER
GO
CREATE TRIGGER InitializeSessionContext ON ALL SERVER
FOR LOGON AS
BEGIN
--Initialize context information that can be altered in the session
EXEC sp_set_session_context @key = N'UsRegion'
,@value = N'Southeast'
--Initialize context information that cannot be altered in the session
EXEC sp_set_session_context @key = N'CannotChange'
,@value = N'CannotChangeThisValue'
,@read_only = 1
END;
Je me suis connecté en tant qu'utilisateur complètement nouveau et j'ai pu extraire les SESSION_CONTEXT
informations:
DECLARE @UsRegion varchar(20)
SET @UsRegion = CONVERT(varchar(20), SESSION_CONTEXT(N'UsRegion'))
SELECT DoThat = @UsRegion
DECLARE @CannotChange varchar(20)
SET @CannotChange = CONVERT(varchar(20), SESSION_CONTEXT(N'CannotChange'))
SELECT DoThat = @CannotChange
J'ai même tenté de modifier les informations de contexte «read_only»:
EXEC sp_set_session_context @key = N'CannotChange'
,@value = N'CannotChangeThisValue'
et a reçu une erreur:
Msg 15664, niveau 16, état 1, procédure sp_set_session_context, ligne 1 [ligne de démarrage par lots 8] Impossible de définir la clé «CannotChange» dans le contexte de la session. La clé a été définie en lecture seule pour cette session.
Une note importante sur les déclencheurs de connexion ( de ce post )!
Un déclencheur d'ouverture de session peut empêcher efficacement les connexions réussies au moteur de base de données pour tous les utilisateurs, y compris les membres du rôle serveur fixe sysadmin. Lorsqu'un déclencheur d'ouverture de session empêche les connexions, les membres du rôle serveur fixe sysadmin peuvent se connecter en utilisant la connexion administrateur dédiée ou en démarrant le moteur de base de données en mode de configuration minimale (-f)
Un inconvénient potentiel est que cela remplit l'instance de contexte de session à l'échelle (pas par base de données). À ce stade, les seules options auxquelles je peux penser sont:
- Nommez vos
Session_Context
paires nom-valeur en les préfixant avec le nom de la base de données afin de ne pas provoquer de collision pour le même nom de type dans une autre base de données. Cela ne résout pas le problème de la prédéfinition de TOUTES les Session_Context
valeurs de nom pour tous les utilisateurs.
- Lorsque le déclencheur de connexion se déclenche, vous avez accès à
EventData
(xml) que vous pouvez utiliser pour extraire l'utilisateur de connexion et en fonction de cela, vous pouvez créer des Session_Context
paires nom-valeur spécifiques .