HOST NAME: примеры (SQL)

Использование HOST_NAME в Microsoft SQL Server на практике
Раздел: Сетевые функции, Системные
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.

Расширенные сценарии использования

Аудит действий в триггере

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

Пример sql
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;

Ограничение доступа по имени рабочей станции в хранимой процедуре

Пример условной логики, основанной на имени хоста (с учетом её ограниченной надежности).

Пример sql
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;

Динамическое имя базы данных для разработчиков

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

Пример sql
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;

Использование вместе с другими системными данными

Комплексный запрос для диагностики активных сеансов.

Пример sql
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;

MS SQL HOST_NAME function comments

En
HOST NAME Returns the workstation name