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

Руководство по работе с функцией USER_ID в Microsoft SQL Server
Раздел: Функции управления системой
USER_ID([ 'user' ]): int

Основные сведения о функции USER_ID

Функция USER_ID в Microsoft SQL Server возвращает идентификационный номер (ID) пользователя базы данных. Этот идентификатор является целым числом (тип int) и уникален в пределах конкретной базы данных. Функция существует в первую очередь для обеспечения обратной совместимости. В новых разработках рекомендуется использовать более современные системные представления, такие как sys.database_principals.

Синтаксис: USER_ID ( [ 'user' ] )

Аргументы:

  • 'user' (необязательный): Имя пользователя базы данных, для которого требуется получить идентификатор. Аргумент имеет тип sysname. Если аргумент не указан, функция возвращает ID текущего пользователя.

Возвращаемое значение: Функция возвращает значение типа int.

  • Если указано имя существующего пользователя базы данных, возвращается его ID.
  • Если аргумент не указан, возвращается ID текущего пользователя.
  • Если указано имя несуществующего пользователя или имя пользователя Windows, не имеющего соответствующего пользователя в базе данных, функция возвращает NULL.
  • Для встроенных ролей базы данных (таких как dbo, guest) также возвращаются их идентификаторы.

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

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

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

SELECT USER_ID() AS CurrentUserID;
CurrentUserID
---------------
5

Пример 2: Получение ID конкретного пользователя базы данных.

SELECT USER_ID('dbo') AS DboUserID, USER_ID('guest') AS GuestUserID;
DboUserID GuestUserID
--------- -----------
1         2

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

SELECT USER_ID('NonExistentUser') AS ID_For_Unknown;
ID_For_Unknown
---------------
NULL

Аналогичные функции в MS SQL Server

  • DATABASE_PRINCIPAL_ID('principal_name'): Более современная и предпочтительная функция. Работает аналогично USER_ID, но поддерживает все типы участников базы данных (пользователи, роли, группы приложений), а не только пользователей. Рекомендуется для использования в новых разработках.
  • SUSER_ID('login'): Возвращает идентификационный номер имени входа на уровне экземпляра SQL Server (сервера), а не на уровне базы данных.
  • SYSTEM_USER: Возвращает имя текущего пользователя, а не его ID.
  • CURRENT_USER: Возвращает имя текущего пользователя (соответствует стандарту SQL).
  • sys.database_principals: Системное представление, которое содержит все сведения об участниках базы данных, включая их имена (name) и идентификаторы (principal_id). Это наиболее гибкий способ получения информации. Например: SELECT principal_id FROM sys.database_principals WHERE name = 'username';

Аналоги в других СУБД

  • PostgreSQL: Используется функция pg_user.usesysid в сочетании с системным представлением. Самостоятельной функции USER_ID нет.
    SELECT usesysid FROM pg_user WHERE usename = CURRENT_USER;
  • Oracle: Аналогом можно считать столбец USER_ID в представлении DBA_USERS или ALL_USERS.
    SELECT user_id FROM dba_users WHERE username = USER;
  • MySQL: Прямого аналога нет. Идентификатор пользователя не является стандартным понятием в этой модели. Для получения информации о пользователе используют системные представления, такие как mysql.user.
  • SQLite: Концепция пользовательских ID в базе данных отсутствует.

Типичные ошибки и особенности

1. Путаница между пользователем базы данных и именем входа на сервер. Функция USER_ID работает только с пользователями базы данных. Передача имени входа Windows или SQL Server Authentication, для которого нет соответствующего пользователя в текущей базе, вернет NULL.

-- Если 'SomeLogin' является именем входа, но не пользователем в этой БД:
SELECT USER_ID('SomeLogin'); -- Вернет NULL

2. Ожидание, что функция всегда вернет не-NULL значение для существующего пользователя. Для встроенных системных пользователей или ролей функция возвращает их ID.

3. Использование функции для проверки существования пользователя. Лучше использовать представление sys.database_principals.

-- Ненадежный способ:
IF USER_ID('SomeUser') IS NOT NULL PRINT 'User exists';
-- Более надежный способ:
IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = 'SomeUser') PRINT 'User exists';

История изменений

Функция USER ID не претерпела значительных синтаксических изменений в последних версиях SQL Server. Основное изменение связано с философией использования. Начиная с SQL Server 2005 и более поздних версий, корпорация Microsoft рекомендует для новых разработок использовать представления совместимости каталогов (sys.*), а не функции, подобные USER_ID. Сама функция сохранена для обеспечения обратной совместимости со старыми версиями и скриптами.

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

Пример 1: Использование в выражении CASE для определения уровня доступа.

Пример sql
SELECT
    CASE USER_ID()
        WHEN USER_ID('dbo') THEN 'Полный доступ (владелец базы данных)'
        WHEN USER_ID('report_user') THEN 'Доступ только для чтения отчетов'
        ELSE 'Стандартный доступ'
    END AS AccessLevel;
AccessLevel
---------------------------------
Полный доступ (владелец базы данных)

Пример 2: Логирование действий с сохранением ID пользователя.

Пример sql
CREATE TABLE dbo.AuditLog (
    LogID int IDENTITY PRIMARY KEY,
    ActionTime datetime DEFAULT GETDATE(),
    UserDB_ID int,
    ActionDescription nvarchar(255)
);

-- Вставка записи в журнал аудита
INSERT INTO dbo.AuditLog (UserDB_ID, ActionDescription)
VALUES (USER_ID(), 'Запущена процедура генерации отчета');

-- Просмотр журнала с именем пользователя
SELECT
    al.ActionTime,
    dp.name AS UserName,
    al.ActionDescription
FROM dbo.AuditLog al
LEFT JOIN sys.database_principals dp ON al.UserDB_ID = dp.principal_id;

Пример 3: Сравнение идентификаторов для условного выполнения кода в хранимой процедуре.

Пример sql
IF USER_ID() = USER_ID('service_account')
BEGIN
    PRINT 'Выполняется автоматическая задача обслуживания.';
    -- Код специальной логики
END
ELSE
BEGIN
    PRINT 'Выполняется задача, инициированная пользователем.';
    -- Стандартная логика
END

Пример 4: Создание динамического SQL с учетом пользователя (с осторожностью).

Пример sql
DECLARE @DynamicSQL nvarchar(MAX);
DECLARE @SchemaName sysname;

-- Предположим, что схема пользователя совпадает с его именем
SELECT @SchemaName = name FROM sys.database_principals WHERE principal_id = USER_ID();

SET @DynamicSQL = N'SELECT COUNT(*) FROM ' + QUOTENAME(@SchemaName) + N'.SomeTable';

-- EXEC sp_executesql @DynamicSQL;
PRINT @DynamicSQL;

MS SQL USER_ID function comments

En
USER ID Returns the identification number for a database user