SUSER ID: примеры (SQL)
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).
SELECT CASE WHEN SUSER_ID() = SUSER_ID('sa') THEN 'Вы вошли как sa' ELSE 'Вы не sa' END AS ПроверкаПрав;ПроверкаПрав ------------- Вы не sa
Пример 2: Журналирование действий с сохранением SID пользователя, а не его имени. Это может быть полезно, если имя входа может измениться, а уникальный идентификатор останется прежним.
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: Использование в представлении для динамической фильтрации данных в зависимости от пользователя.
CREATE VIEW dbo.MyPersonalData AS
SELECT * FROM dbo.SensitiveData
WHERE ResponsibleSID = SUSER_ID();
-- Каждый пользователь увидит только строки, где ResponsibleSID равен его собственному SID.Пример 4: Комбинация с SUSER_SNAME для полного аудита - хранение SID и отображение имени.
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, как у текущего пользователя. Это может быть полезно в скриптах миграции.
SELECT name FROM sys.server_principals WHERE sid = (SELECT sid FROM sys.syslogins WHERE loginname = ORIGINAL_LOGIN());