Da Sie anscheinend SQL Server 2016 verwenden, möchte ich eine weitere " mögliche " Option streichen - SESSION_CONTEXT
.
Leonard Lobels Artikel " Status in SQL Server 2016 mitSESSION_CONTEXT
teilen" enthält einige sehr gute Informationen zu dieser neuen Funktionalität in SQL Server 2016.
Einige wichtige Punkte zusammenfassen:
Wenn Sie schon immer den Sitzungsstatus für alle gespeicherten Prozeduren und Stapel während der gesamten Lebensdauer einer Datenbankverbindung freigeben wollten, werden Sie begeistert sein SESSION_CONTEXT
. Wenn Sie eine Verbindung zu SQL Server 2016 herstellen, erhalten Sie ein Stateful-Wörterbuch oder eine so genannte State-Bag-Datei, in der Sie Werte wie Zeichenfolgen und Zahlen speichern und dann über einen von Ihnen zugewiesenen Schlüssel abrufen können. Im Fall von SESSION_CONTEXT
ist der Schlüssel eine beliebige Zeichenfolge, und der Wert ist eine sql_variant, was bedeutet, dass er eine Vielzahl von Typen aufnehmen kann.
Sobald Sie etwas gespeichert haben SESSION_CONTEXT
, bleibt es dort, bis die Verbindung geschlossen wird. Es wird in keiner Tabelle in der Datenbank gespeichert, sondern lebt nur im Speicher, solange die Verbindung besteht. Und jeder T-SQL-Code, der in gespeicherten Prozeduren, Triggern, Funktionen oder was auch immer ausgeführt wird, kann alles teilen, worauf Sie sich einlassen
SESSION_CONTEXT
.
Das Nächste, was wir bisher hatten CONTEXT_INFO
, war das Speichern und Freigeben eines einzelnen Binärwerts mit einer Länge von bis zu 128 Byte. Dies ist weitaus weniger flexibel als das Wörterbuch, mit SESSION_CONTEXT
dem Sie mehrere Werte verschiedener Daten unterstützen Typen.
SESSION_CONTEXT
ist einfach zu bedienen, rufen Sie einfach sp_set_session_context auf, um den Wert mit einem gewünschten Schlüssel zu speichern. Wenn Sie dies tun, geben Sie natürlich den Schlüssel und den Wert an, aber Sie können auch den Parameter read_only auf true setzen. Dadurch wird der Wert im Sitzungskontext gesperrt, sodass er für den Rest der Lebensdauer der Verbindung nicht geändert werden kann. So ist es beispielsweise für eine Clientanwendung einfach, diese gespeicherte Prozedur aufzurufen, um einige Sitzungskontextwerte direkt nach dem Herstellen der Datenbankverbindung festzulegen. Wenn die Anwendung dabei den Parameter read_only festlegt, können die gespeicherten Prozeduren und anderer T-SQL-Code, der dann auf dem Server ausgeführt wird, nur den Wert lesen. Sie können nicht ändern, was von der auf dem Client ausgeführten Anwendung festgelegt wurde.
Als Test habe ich einen Server-Login-Trigger erstellt, der einige CONTEXT_SESSION
Informationen festlegt - einer der SESSION_CONTEXT
war auf gesetzt @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;
Ich habe mich als völlig neuer Benutzer angemeldet und konnte die folgenden SESSION_CONTEXT
Informationen extrahieren :
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
Ich habe sogar versucht, die Kontextinformationen 'read_only' zu ändern:
EXEC sp_set_session_context @key = N'CannotChange'
,@value = N'CannotChangeThisValue'
und erhielt einen Fehler:
Nachricht 15664, Ebene 16, Status 1, Prozedur sp_set_session_context, Zeile 1 [Stapelstartzeile 8] Der Schlüssel 'CannotChange' kann im Sitzungskontext nicht festgelegt werden. Der Schlüssel wurde für diese Sitzung als read_only festgelegt.
Ein wichtiger Hinweis zu Login-Triggern ( aus diesem Beitrag )!
Ein Anmeldetrigger kann erfolgreiche Verbindungen zum Datenbankmodul für alle Benutzer, einschließlich Mitglieder der festen Serverrolle sysadmin, effektiv verhindern. Wenn ein Anmeldetrigger Verbindungen verhindert, können Mitglieder der festen Serverrolle sysadmin über die dedizierte Administratorverbindung oder durch Starten des Datenbankmoduls im minimalen Konfigurationsmodus (-f) eine Verbindung herstellen.
Ein möglicher Nachteil besteht darin, dass dies den Sitzungskontext instanzweit ausfüllt (nicht pro Datenbank). An diesem Punkt sind die einzigen Optionen, die mir einfallen, folgende:
- Benennen Sie Ihre
Session_Context
Name-Wert-Paare, indem Sie ihnen den Datenbanknamen voranstellen, um keine Kollision für denselben Typnamen in einer anderen Datenbank zu verursachen. Dies löst nicht das Problem, ALLE Session_Context
Namenswerte für alle Benutzer vorab zu definieren .
- Wenn der Anmeldeauslöser ausgelöst wird, haben Sie Zugriff auf
EventData
(xml), mit dem Sie den Anmeldebenutzer extrahieren können. Auf dieser Grundlage können Sie bestimmte Session_Context
Name-Wert-Paare erstellen .