HOST NAME: примеры (SQL)
HOST_NAME: nvarchar(128)Основные сведения о функции HOST_NAME
Функция HOST_NAME() в MS SQL Server возвращает имя рабочей станции, с которой установлено текущее соединение с экземпляром SQL Server. Эта функция не требует аргументов и всегда вызывается с пустыми скобками. Возвращаемым значением является строка nvarchar(128).
Имя рабочей станции, которое возвращает функция, соответствует значению, переданному клиентским приложением при установлении соединения. Это значение часто, но не всегда, совпадает с сетевым именем компьютера. Например, в приложениях, использующих библиотеку .NET SqlClient, имя хоста можно задать явно в строке подключения с помощью параметра Workstation ID.
Типичные варианты использования функции включают в себя аудит действий пользователей (для регистрации того, с какого компьютера выполнено то или иное действие), а также применение в логике безопасности, например, для ограничения доступа к определенным данным только с доверенных хостов.
Примеры базового применения
Простое получение имени хоста
Самый простой способ вызова функции без какого-либо контекста.
SELECT HOST_NAME() AS [Имя хоста текущего соединения];Имя хоста текущего соединения ---------------------------------------- MYWORKSTATION
Использование в запросе с другими данными
Функцию можно использовать в SELECT-запросе вместе с другими системными функциями.
SELECT
SUSER_NAME() AS [Имя пользователя],
HOST_NAME() AS [Имя компьютера],
APP_NAME() AS [Приложение]
FROM sys.dm_exec_sessions
WHERE session_id = @@SPID;Имя пользователя Имя компьютера Приложение -------------- --------------- ---------------------- MYDOMAIN\\User1 MYWORKSTATION Microsoft SQL Server Management Studio - Запрос
Похожие функции в MS SQL Server
В MS SQL Server существует несколько системных функций, предоставляющих контекстную информацию о соединении и пользователе:
- HOST_ID(): Возвращает идентификатор рабочей станции. Это значение часто менее информативно, чем имя, и представляет собой строку, генерируемую клиентской библиотекой.
- APP_NAME(): Возвращает имя клиентского приложения, установившего соединение.
- SUSER_NAME() / SYSTEM_USER: Возвращает имя входа, связанное с текущим контекстом безопасности.
- SESSION_USER и CURRENT_USER: Возвращают имя пользователя базы данных в текущем контексте.
Функцию HOST_NAME() предпочтительнее использовать, когда нужна текстовая идентификация клиентского компьютера для логирования или условной логики. HOST_ID() применяется реже, так как её значение обычно менее читаемо. Для комплексного аудита все эти функции часто используются вместе.
Аналоги в других СУБД и языках
PostgreSQL
В PostgreSQL прямого аналога нет, но информацию о подключении можно получить из системных представлений, таких как pg_stat_activity.
SELECT pid, usename, application_name, client_addr, client_hostname
FROM pg_stat_activity
WHERE pid = pg_backend_pid();pid | usename | application_name | client_addr | client_hostname ------+---------+------------------------+--------------+---------------- 12345 | postgres| psql | 192.168.1.10 | client-pc
Oracle
В Oracle используется функция SYS_CONTEXT('USERENV', 'HOST').
SELECT SYS_CONTEXT('USERENV', 'HOST') AS host_name FROM DUAL;HOST_NAME ---------------- oracle-client
MySQL
В MySQL аналогом является системная переменная сессии @@hostname, но она возвращает имя сервера, а не клиента. Информацию о клиентском хосте можно получить из переменной @@proxy_user или из системных таблиц процесса, хотя это не всегда надежно.
SHOW VARIABLES LIKE 'hostname';Variable_name | Value ------------- | ----- hostname | mysql-server
SQLite
SQLite является встраиваемой СУБД и не имеет концепции сетевых соединений или клиентских хостов, поэтому аналогичной функции не существует.
Типичные ошибки и предостережения
Доверие к значению функции
Основная ошибка — полагаться на значение HOST_NAME() как на абсолютно надежный идентификатор для критически важных проверок безопасности. Это значение задается клиентом и потенциально может быть подменено.
-- Ненадежная проверка
IF HOST_NAME() = 'TRUSTED-PC'
PRINT 'Доступ разрешен.';
ELSE
THROW 50000, 'Доступ запрещен!', 1;Для серьезных ограничений доступа необходимо использовать другие механизмы, например, аутентификацию Windows или проверку IP-адресов на уровне сети.
Использование в вычисляемых столбцах или индексах
Поскольку HOST_NAME() является недетерминированной функцией (её результат зависит от контекста выполнения, а не только от входных данных), её нельзя использовать в детерминированных вычисляемых столбцах или индексированных представлениях.
-- Вызовет ошибку
CREATE TABLE AuditLog (
ID INT IDENTITY,
ActionDate DATETIME DEFAULT GETDATE(),
HostName AS HOST_NAME() PERSISTED -- Ошибка: Недетерминированная функция
);История изменений функции
Функция HOST_NAME() существует в SQL Server с ранних версий и сохраняет свою основную сигнатуру и поведение. Существенных изменений в её работе в последних версиях (SQL Server 2016, 2017, 2019, 2022) не было. Её возвращаемый тип данных — nvarchar(128) — остается неизменным на протяжении многих выпусков.
Однако в современных версиях SQL Server, особенно при использовании функций Always On или других технологий высокой доступности, важно помнить, что функция возвращает имя клиентской рабочей станции, а не сервера. Для получения имени экземпляра сервера следует использовать функцию @@SERVERNAME.
Расширенные сценарии использования
Аудит действий в триггере
Часто функция применяется в триггерах для отслеживания источника изменений данных.
CREATE TRIGGER trg_AuditEmployees
ON Employees
AFTER UPDATE, INSERT, DELETE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO EmployeeAudit (EmployeeID, ChangedBy, HostName, ChangeDate, Action)
SELECT
COALESCE(i.EmployeeID, d.EmployeeID),
SUSER_NAME(),
HOST_NAME(),
GETDATE(),
CASE
WHEN i.EmployeeID IS NOT NULL AND d.EmployeeID IS NOT NULL THEN 'UPDATE'
WHEN i.EmployeeID IS NOT NULL THEN 'INSERT'
ELSE 'DELETE'
END
FROM inserted i
FULL OUTER JOIN deleted d ON i.EmployeeID = d.EmployeeID;
END;Ограничение доступа по имени рабочей станции в хранимой процедуре
Пример условной логики, основанной на имени хоста (с учетом её ограниченной надежности).
CREATE PROCEDURE usp_GetSensitiveData
AS
BEGIN
DECLARE @CurrentHost NVARCHAR(128) = HOST_NAME();
IF @CurrentHost IN ('FINANCE-PC-01', 'FINANCE-PC-02')
BEGIN
-- Разрешить полный доступ для определенных хостов
SELECT * FROM dbo.SensitiveFinancialData;
END
ELSE
BEGIN
-- Для остальных вернуть только агрегированные данные
SELECT YEAR(Date) AS ReportYear, SUM(Amount) AS TotalAmount
FROM dbo.SensitiveFinancialData
GROUP BY YEAR(Date);
END
END;Динамическое имя базы данных для разработчиков
Сценарий, в котором имя хоста используется для автоматического переключения на персональную базу данных разработчика.
DECLARE @DevDBName NVARCHAR(255) = 'DevDatabase_' + REPLACE(HOST_NAME(), '-', '_');
IF DB_ID(@DevDBName) IS NOT NULL AND HOST_NAME() LIKE 'DEV-%'
BEGIN
PRINT 'Переключение на базу данных разработчика: ' + @DevDBName;
EXEC('USE ' + QUOTENAME(@DevDBName) + ';');
END
ELSE
BEGIN
PRINT 'Используется основная рабочая база данных.';
END;Использование вместе с другими системными данными
Комплексный запрос для диагностики активных сеансов.
SELECT
s.session_id,
s.login_name,
s.host_name,
s.program_name,
t.text AS [Последняя команда SQL],
c.client_net_address,
s.login_time
FROM sys.dm_exec_sessions s
LEFT JOIN sys.dm_exec_connections c ON s.session_id = c.session_id
OUTER APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t
WHERE s.is_user_process = 1
ORDER BY s.login_time DESC;