Am Sybase SQL Anywhere, der zwischendrin mal auf den schönen Namen "Sybase Adaptive Server Anywhere" hörte, gibt es ein Feature, was ich am "Microsoft SQL Server" besonders vermisse: globale Variable, die während einer gesamten Session erreichbar sind.
Sie haben einen ähnlichen Gültigkeitsbereich, wie "normale" temporäre Tabellen beim SQL Server. Man deklariert sie einmal, kann der Wert dann beliebig setzen und in allen Batches in dieser Session darauf zugreifen.

Eigenartigerweise bietet der SQl Srever ein Featrue an, das etwas in diese Richtig geht:
mit CONTEXT_INFO kann man genau einen 128 Bytes langen Wert speichern.

Beispiel

Angenommen eine Anwendung muss in Ausnahmenfällen mal eine Verbindung zu einer Datenbank aufbauen, um eine Tabelle zu erweitern oder ein Backup durchzuführen. Normale Benutzer haben dazu nicht die entsprechenden Rechte. Die Anwendung meldet sich mit dem Datenbank-Besitzer "MyDBO" an, um bspw. ein neues benutzerdefiniertes Feld anzulegen. Selbstverständlich werden alle ändernden Operationen in einer Tabelle protokolliert, dazu kann der Benutzername mittels "user_name()" ermittelt werden, z.B. "Thomas".
Die Dinge aus der Admin-Verbindung sollen auch protokolliert werden. Hier soll jetzt aber nicht der Name "MyDBO" notiert werden, sondern der Verursacher: "Thomas".

Zu diesem Zweck kann man gleich nach dem Aufbauen der Vrebindung den Namen des Benutzers in die CONTEXT_INFO schreiben, falls es sich um so eine Sonderverbindung handelt:

declare @context_info varbinary(128);
set @context_info = cast('thomas' as varbinary(128))
set context_info @context_info

Um den Wert abzufragen, muss man beim SQL Server 2000 tief in die Trickkiste greifen und eine Systemtabelle abfragen:

select cast(context_info as varchar(128))
from sysprocesses
where spid=@@spid

Wenn man nun wissen will, wer die zu protokollierende Aktion veranlasst hat, kannman das so erfragen:

declare @user_info varchar(128);
set @user_info = (select cast(context_info as varchar(128)) from sysprocesses where spid=@@spid)
select case
when @user_info = ''
then user_name()
else @user_info
end as "User_name"

Am SQL Server 2005 hat sich daran nicht viel verändert. Immerhin muss man jetzt nicht mehr die Systemtabelle abfragen:

SELECT cast(CONTEXT_INFO() as varchar(128))

Im konkreten Beispiel würde sich das vereinfachend auswirken:

select case
when cast(CONTEXT_INFO() as varchar(128)) = ''
then user_name()
else cast(CONTEXT_INFO() as varchar(128))
end as "User_name"

Das ist für den Obige Fall schon eine akzeptable Lösung. Leider gibt es damit nur eine einzige "globale" Variable. Wenn man mehr benötigt, dann muss man sich das in temporären Tabellen speichern. Schade, der Overhead wäre zu vermeiden…