USER NAME: примеры (SQL)
USER_NAME([id]): nvarchar(128)Функция USER_NAME в MS SQL Server
Функция USER_NAME в Microsoft SQL Server возвращает имя пользователя базы данных для указанного идентификационного номера. Эта функция принадлежит к категории системных функций, работающих с метаданными безопасности.
Основное назначение функции — преобразование идентификатора пользователя базы данных (principal_id) в его символьное имя. Это полезно при аудите, отладке и формировании отчетов, когда в системных таблицах или представлениях хранятся числовые идентификаторы, но для восприятия требуются читаемые имена.
Синтаксис функции:
USER_NAME ( [ id ] )
Аргументы:
- id (необязательный) — идентификационный номер пользователя базы данных (principal_id) типа int. Если аргумент не указан, функция возвращает имя текущего пользователя.
Возвращаемое значение:
- Тип данных nvarchar(128).
- Если указан существующий id, возвращается имя пользователя, связанное с этим идентификатором.
- Если указан NULL или аргумент опущен, возвращается имя текущего пользователя базы данных.
- Если указан несуществующий числовой id, функция возвращает NULL.
Примеры использования USER_NAME
Возврат имени текущего пользователя:
SELECT USER_NAME() AS CurrentUserName;CurrentUserName dbo
Возврат имени пользователя по известному идентификатору (например, 1):
SELECT USER_NAME(1) AS UserNameById;UserNameById dbo
Использование с аргументом NULL:
SELECT USER_NAME(NULL) AS UserNameNull;UserNameNull dbo
Попытка получить имя для несуществующего идентификатора:
SELECT USER_NAME(999999) AS NonExistentUser;NonExistentUser NULL
Похожие функции в MS SQL Server
- SUSER_NAME([server_user_id]) — возвращает имя входа на уровне экземпляра сервера. Применяется, когда требуется информация об имени входа SQL Server или Windows, а не о пользователе базы данных.
- SYSTEM_USER — функция без аргументов, возвращающая имя входа текущего контекста безопасности на уровне сервера. Это аналогично SUSER_NAME() без параметра.
- CURRENT_USER — функция без аргументов, возвращающая имя текущего пользователя базы данных. Поведение идентично USER_NAME() без параметра, но соответствует стандарту SQL.
- ORIGINAL_LOGIN() — возвращает имя входа, с которым пользователь изначально подключился к экземпляру. Полезна для аудита в сценариях олицетворения (EXECUTE AS).
Выбор функции зависит от контекста: USER_NAME() работает на уровне базы данных, SUSER_NAME() и SYSTEM_USER — на уровне сервера. CURRENT_USER предпочтительнее для кросс-платформенной совместимости.
Аналоги функции в других СУБД
MySQL: Функция USER() возвращает имя пользователя и хост для текущего сеанса. Аналогом USER_NAME(id) в чистом виде нет.
SELECT USER();'root@localhost'
Oracle: Псевдостолбец USER возвращает имя текущего пользователя. Для получения имени по ID можно запросить системное представление ALL_USERS.
SELECT USER FROM DUAL;SYSTEM
PostgreSQL: Функция current_user возвращает имя текущего пользователя. Информация о пользователях доступна в представлении pg_user.
SELECT current_user;postgres
SQLite: Концепция пользователей базы данных отсутствует. Управление доступом обычно осуществляется на уровне файловой системы.
Sybase ASE: Функция USER_NAME([uid]) аналогична по синтаксису и поведению MS SQL Server.
Типичные ошибки
Передача нечислового аргумента приводит к ошибке преобразования типов:
SELECT USER_NAME('admin');Msg 8114, Level 16, State 5, Line 1 Error converting data type varchar to int.
Ожидание возврата имени пользователя для идентификатора, относящегося к роли, а не к пользователю. Роли также являются участниками (principals), но USER_NAME для них возвращает NULL:
-- Пытаемся получить имя для идентификатора роли 'public' (обычно 0)
SELECT USER_NAME(0);NULL
Использование функции для идентификаторов участников уровня сервера (логинов). USER_NAME работает только с пользователями базы данных:
-- ID 1 в базе данных может быть пользователем 'dbo',
-- а на сервере — логином 'sa'. Это разные сущности.
-- Следующий запрос вернет имя пользователя БД, а не логина.
SELECT USER_NAME(1);Изменения в последних версиях
В актуальных версиях Microsoft SQL Server (2016 и новее) значительных изменений в поведении или синтаксисе функции USER NAME не было. Функция сохраняет обратную совместимость с предыдущими версиями.
Отмечается, что возвращаемый тип данных nvarchar(128) остался неизменным, несмотря на то что в SQL Server 2012 и выше максимальная длина имен участников может достигать 128 символов (в более старых версиях — 256 для SQL Server 2000).
Расширенные примеры использования
Сопоставление идентификаторов пользователей с их именами в системном представлении sys.database_principals:
SELECT principal_id, name, type_desc,
USER_NAME(principal_id) AS NameViaFunction
FROM sys.database_principals
WHERE type IN ('S', 'U', 'G') -- SQL пользователь, пользователь Windows, группа Windows
ORDER BY principal_id;principal_id name type_desc NameViaFunction 1 dbo SQL_USER dbo 3 guest SQL_USER guest 4 INFORMATIKA\User1 WINDOWS_USER INFORMATIKA\User1
Использование в триггере для аудита изменений с сохранением имени пользователя:
CREATE TABLE dbo.EmployeeAudit (
AuditID INT IDENTITY PRIMARY KEY,
EmployeeID INT NOT NULL,
ChangedBy NVARCHAR(128) DEFAULT USER_NAME(),
ChangeTime DATETIME DEFAULT GETDATE(),
Action CHAR(1)
);Определение владельца объекта в базе данных:
SELECT OBJECT_NAME(object_id) AS ObjectName,
USER_NAME(principal_id) AS OwnerName
FROM sys.objects
WHERE principal_id IS NOT NULL;Использование в динамическом SQL для построения запроса с учетом текущего пользователя:
DECLARE @CurrentUser NVARCHAR(128) = USER_NAME();
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'SELECT * FROM dbo.SensitiveData WHERE Responsible = ''' + @CurrentUser + '''';
EXEC sp_executesql @SQL;Сравнение текущего пользователя с владельцем схемы:
IF USER_NAME() <> SCHEMA_NAME()
PRINT 'Текущий пользователь не является владельцем схемы по умолчанию.';