@@SPID: примеры (SQL)
@@SPID: intФункция @@SPID в MS SQL Server
Функция @@SPID является системной функцией Microsoft SQL Server, которая возвращает целочисленное значение. Это значение представляет собой идентификатор процесса сервера (Server Process ID) для текущего пользовательского сеанса.
Основное назначение функции — идентификация конкретного сеанса подключения к серверу баз данных. Каждому установленному соединению с SQL Server присваивается уникальный SPID на время его существования. Этот идентификатор используется для мониторинга активности, диагностики проблем, управления блокировками и контроля выполняемых запросов.
Функция не принимает никаких аргументов или параметров. Для ее вызова используется синтаксис SELECT @@SPID или PRINT @@SPID.
Возвращаемое значение имеет тип данных smallint. Это целое число в диапазоне от 0 до 65535, которое уникально идентифицирует сеанс в рамках экземпляра сервера. Значения SPID могут повторно использоваться системой после закрытия соединения и освобождения идентификатора.
Простые примеры использования
Самый простой способ получить идентификатор текущего сеанса — выполнить запрос с выборкой значения функции.
SELECT @@SPID AS 'Текущий SPID';Текущий SPID --------------- 53
Функцию можно использовать для вывода информации в сообщения.
PRINT 'Идентификатор текущего сеанса: ' + CAST(@@SPID AS VARCHAR);Идентификатор текущего сеанса: 53
Значение SPID часто включают в логирование или отладочную информацию.
DECLARE @CurrentSPID smallint = @@SPID;
SELECT
@CurrentSPID AS SessionID,
SYSTEM_USER AS LoginName,
DB_NAME() AS DatabaseName;SessionID LoginName DatabaseName --------- --------- ------------- 53 sa master
Альтернативные методы в MS SQL
В Microsoft SQL Server существуют другие способы получения информации о сеансе, которые могут предоставить дополнительные данные или контекст.
Функция SESSION_ID()
Начиная с SQL Server 2016, появилась функция SESSION_ID(), которая является синонимом @@SPID и возвращает тот же идентификатор. Она соответствует стандарту ANSI SQL.
Динамическое административное представление sys.dm_exec_sessions
Это представление предоставляет расширенную информацию обо всех активных сеансах. Для получения SPID текущего сеанса можно выполнить фильтрацию.
SELECT session_id, login_name, host_name, program_name
FROM sys.dm_exec_sessions
WHERE session_id = @@SPID;Системная функция HOST_ID()
Функция HOST_ID() возвращает идентификатор рабочей станции, а не сеанса, но часто используется вместе с @@SPID для комплексной диагностики.
Аналоги в других СУБД
MySQL
В MySQL используется функция CONNECTION_ID(), которая возвращает идентификатор подключения для текущего соединения.
SELECT CONNECTION_ID();CONNECTION_ID() --------------- 12345
PostgreSQL
В PostgreSQL применяется функция pg_backend_pid(), возвращающая идентификатор процесса сервера, связанного с текущим сеансом.
SELECT pg_backend_pid();pg_backend_pid --------------- 7890
Oracle
В Oracle Database для получения идентификатора сессии используется запрос к представлению V$SESSION с фильтрацией по аудиосидентификатору.
SELECT sid, serial#, username
FROM v$session
WHERE audsid = USERENV('SESSIONID');SQLite
SQLite, будучи встраиваемой СУБД, не имеет концепции серверных идентификаторов процессов, поэтому прямой аналог отсутствует.
Типичные ошибки применения
Одна из частых ошибок — попытка использовать @@SPID как константу для всех сеансов или предполагать, что значение будет уникальным вечно. SPID переиспользуется системой.
-- Неправильное предположение о постоянстве SPID
CREATE TABLE #SessionLog (
LogID int,
SPID smallint DEFAULT @@SPID -- Здесь будет зафиксирован SPID на момент создания таблицы
);
-- При вставке данных в разных сеансах все записи получат один SPID
INSERT INTO #SessionLog (LogID) VALUES (1);Еще одна ошибка — ожидание, что @@SPID можно использовать для надежной аутентификации или контроля безопасности.
-- Ненадежный способ проверки сеанса
IF @@SPID = 55
BEGIN
PRINT 'Это специальный сеанс';
END;
-- После переподключения SPID может измениться или тот же ID получить другой пользовательИзменения в последних версиях
Функция @@SPID остается неизменной в своих основных характеристиках на протяжении многих версий SQL Server. Важное уточнение появилось в документации, касающееся работы в средах с высоким уровнем доступности и в распределенных транзакциях.
В SQL Server 2016 была добавлена функция SESSION_ID() как стандартизированный аналог, но @@SPID сохраняется для обратной совместимости.
В Azure SQL Database функция работает аналогично локальным экземплярам, возвращая уникальный идентификатор сеанса в рамках конкретной базы данных.
Расширенные примеры применения
Использование в мониторинге блокировок
Функция помогает идентифицировать текущий сеанс при анализе блокировок.
-- Находим блокировки для текущего сеанса
SELECT
request_session_id,
resource_type,
resource_description,
request_mode,
request_status
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID;Применение в триггерах для аудита
В триггерах можно фиксировать SPID для отслеживания источников изменений.
CREATE TABLE AuditLog (
ChangeID int IDENTITY,
TableName varchar(100),
ChangeType varchar(10),
ChangeDate datetime DEFAULT GETDATE(),
SessionID smallint,
UserName varchar(100)
);
CREATE TRIGGER trg_AuditEmployees
ON Employees AFTER INSERT, UPDATE, DELETE
AS
BEGIN
INSERT INTO AuditLog (TableName, ChangeType, SessionID, UserName)
VALUES ('Employees',
CASE WHEN EXISTS(SELECT * FROM inserted) AND EXISTS(SELECT * FROM deleted) THEN 'UPDATE'
WHEN EXISTS(SELECT * FROM inserted) THEN 'INSERT'
ELSE 'DELETE' END,
@@SPID,
SYSTEM_USER);
END;Динамическое управление соединениями
С помощью @@SPID можно управлять конкретными сеансами.
-- Завершение определенного сеанса (требуются соответствующие права)
DECLARE @TargetSPID smallint = 55;
IF @TargetSPID <> @@SPID AND EXISTS(SELECT * FROM sys.sysprocesses WHERE spid = @TargetSPID)
BEGIN
EXEC('KILL ' + CAST(@TargetSPID AS varchar));
PRINT 'Сеанс ' + CAST(@TargetSPID AS varchar) + ' завершен.';
END;Использование в распределенных запросах
При работе с связанными серверами можно отслеживать исходный сеанс.
-- Логирование запросов к удаленным источникам
INSERT INTO RemoteQueryLog (QueryText, LocalSPID, ExecutionTime)
VALUES ('SELECT * FROM LinkedServer.DB.dbo.Table1', @@SPID, GETDATE());