SUSER ID: примеры (SQL)

Функция SUSER_ID в SQL Server для получения идентификатора
Раздел: Функции управления системой
SUSER_ID([ 'login' ]): smallint

Описание функции SUSER_ID

Функция SUSER_ID в Microsoft SQL Server возвращает идентификационный номер входа (login identification number) для пользователя. Этот идентификатор, также известный как SID (Security Identifier), является уникальным в рамках экземпляра SQL Server и используется системой безопасности.

Функция может применяться в сценариях аудита, для сравнения или логирования идентификаторов пользователей, а также в запросах, где требуется ссылаться на пользователя по его системному идентификатору, а не по имени.

Синтаксис и аргументы

 SUSER_ID ( [ 'login' ] )

Аргумент 'login' является необязательным. Это имя входа пользователя, для которого нужно получить идентификатор. Имя входа может быть задано как sysname (nchar(128)). Если аргумент не указан, функция возвращает SID для текущего контекста безопасности.

Возвращаемое значение имеет тип int. Если указанное имя входа недействительно или у пользователя нет разрешения на его просмотр, функция возвращает NULL. Для встроенных системных имен входа, таких как 'sa', возвращается фиксированный идентификатор.

Примеры использования SUSER_ID

Пример 1: Получение SID для текущего пользователя.

SELECT SUSER_ID() AS 'Текущий SID';
Текущий SID
-----------
10

Пример 2: Получение SID для конкретного имени входа (например, 'sa').

SELECT SUSER_ID('sa') AS 'SID для sa';
SID для sa
----------
1

Пример 3: Попытка получить SID для несуществующего имени входа.

SELECT SUSER_ID('NonExistentLogin') AS 'SID';
SID
---
NULL

Пример 4: Использование в предложении WHERE для фильтрации по SID.

SELECT name FROM sys.sql_logins WHERE sid = SUSER_ID('MyLogin');
name
-------
MyLogin

Похожие функции в MS SQL Server

SUSER_SNAME() является обратной функцией. Она принимает SID (типа varbinary(85)) и возвращает соответствующее имя входа типа nvarchar(128). Ее удобно использовать, когда известен идентификатор, но нужно получить логин.

SYSTEM_USER и CURRENT_USER возвращают имена, а не идентификаторы. SYSTEM_USER возвращает текущее имя входа, а CURRENT_USER - имя пользователя в текущей базе данных. SUSER_ID предпочтительнее, когда требуется уникальный числовой ключ для связи или сравнения, например, для хранения в столбце с типом int.

ORIGINAL_LOGIN() возвращает имя входа, с которым пользователь первоначально подключился к экземпляру, что полезно в контексте олицетворения (EXECUTE AS). Для получения его SID можно использовать комбинацию SUSER_ID(ORIGINAL_LOGIN()).

Аналоги в других системах управления базами данных

MySQL не имеет прямой аналогии. Ближайшим концептом может быть функция USER(), возвращающая имя текущего пользователя и хост. Для получения идентификатора можно запрашивать данные из системных таблиц, но это зависит от механизма хранения.

Oracle использует псевдостолбец UID, который возвращает целочисленный идентификатор пользователя текущей сессии.

SELECT UID FROM DUAL;
UID
---
102

PostgreSQL предоставляет функцию pg_get_userbyid(roleid oid) для получения имени пользователя по OID. OID пользователя можно получить из каталога pg_roles. Прямой функции для получения ID по имени нет, требуется запрос.

SELECT oid FROM pg_roles WHERE rolname = CURRENT_USER;

SQLite не имеет встроенной системы пользователей, аналогичные функции отсутствуют.

Sybase ASE (близкий родственник SQL Server) также поддерживает функцию SUSER_ID() с аналогичной семантикой.

Распространенные ошибки

Ошибка 1: Передача имени входа в неправильном формате или без кавычек. Функция ожидает строковый аргумент.

SELECT SUSER_ID(MyLogin); -- Ошибка
Msg 207, Level 16, State 1: Invalid column name 'MyLogin'.

Ошибка 2: Путаница между SUSER_ID и USER_ID. USER_ID возвращает идентификатор пользователя базы данных, а не имени входа на уровне сервера. Их значения не совпадают.

SELECT SUSER_ID() AS ServerSID, USER_ID() AS DbUserID;
ServerSID DbUserID
--------- ----------
10        5

Ошибка 3: Ожидание, что SID всегда будет постоянным для Windows-пользователя. SID имени входа SQL Server, созданного на основе пользователя Windows, действительно соответствует SID Windows. Однако SID для встроенных или SQL-логинов генерируется SQL Server и уникален только в его контексте.

Изменения в последних версиях

В SQL Server 2000 и более ранних версиях функция SUSER_ID могла принимать числовой аргумент (SID типа varbinary) и возвращать соответствующее имя входа. Это поведение было изменено. Начиная с SQL Server 2005, для получения имени по SID следует использовать функцию SUSER_SNAME().

В текущих версиях SQL Server (2012 и новее) функция SUSER_ID сохраняет стабильную семантику, описанную в разделе "Базовая информация". Основное внимание при обновлениях уделяется безопасности и совместимости, без существенных изменений в работе самой функции.

Расширенные примеры применения

Пример 1: Сравнение идентификаторов для проверки, является ли текущий пользователь системным администратором (sa).

Пример sql
SELECT CASE WHEN SUSER_ID() = SUSER_ID('sa') THEN 'Вы вошли как sa' ELSE 'Вы не sa' END AS ПроверкаПрав;
ПроверкаПрав
-------------
Вы не sa

Пример 2: Журналирование действий с сохранением SID пользователя, а не его имени. Это может быть полезно, если имя входа может измениться, а уникальный идентификатор останется прежним.

Пример sql
CREATE TABLE dbo.AuditLog (
    LogID INT IDENTITY PRIMARY KEY,
    ActionTime DATETIME DEFAULT GETDATE(),
    UserSID INT DEFAULT SUSER_ID(),
    ActionDescription NVARCHAR(500)
);
INSERT INTO dbo.AuditLog (ActionDescription) VALUES ('Просмотр конфиденциальных данных');
SELECT * FROM dbo.AuditLog;
LogID ActionTime           UserSID ActionDescription
----- -------------------- ------- ---------------------------
1     2023-10-27 14:35:00 10      Просмотр конфиденциальных данных

Пример 3: Использование в представлении для динамической фильтрации данных в зависимости от пользователя.

Пример sql
CREATE VIEW dbo.MyPersonalData AS
SELECT * FROM dbo.SensitiveData
WHERE ResponsibleSID = SUSER_ID();
-- Каждый пользователь увидит только строки, где ResponsibleSID равен его собственному SID.

Пример 4: Комбинация с SUSER_SNAME для полного аудита - хранение SID и отображение имени.

Пример sql
SELECT 
    al.ActionTime,
    SUSER_SNAME(al.UserSID) AS LoginName, -- Преобразование SID обратно в имя
    al.ActionDescription
FROM dbo.AuditLog al;
ActionTime           LoginName ActionDescription
------------------- --------- ---------------------------
2023-10-27 14:35:00 MyDomain\User1 Просмотр конфиденциальных данных

Пример 5: Определение, был ли создан логин с таким же SID, как у текущего пользователя. Это может быть полезно в скриптах миграции.

Пример sql
SELECT name FROM sys.server_principals WHERE sid = (SELECT sid FROM sys.syslogins WHERE loginname = ORIGINAL_LOGIN());

MS SQL SUSER_ID function comments

En
SUSER ID Returns the login identification number for the user's login name