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

Получение идентификатора базы данных через DB_ID
Раздел: Функции работы с метаданными
DB_ID('[ database_name ]'): smallint

Описание функции DB_ID

Функция DB_ID в Microsoft SQL Server возвращает числовой идентификатор (ID) базы данных. Этот идентификатор является уникальным в пределах экземпляра SQL Server. Функция часто используется в сценариях администрирования, динамического SQL, а также при взаимодействии с системными представлениями, которые оперируют идентификаторами объектов.

Функция используется, когда необходимо получить внутренний идентификатор базы данных по ее имени или проверить существование базы. Этот идентификатор используется в системных представлениях, таких как sys.databases или sys.database_files, для связей между объектами.

Аргументы

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

Возвращаемое значение

smallint: Функция возвращает идентификатор базы данных. Если указанное имя базы данных не существует, функция возвращает NULL. Для системных баз данных, таких как master или tempdb, возвращаются фиксированные значения.

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

Пример получения ID текущей базы данных.

SELECT DB_ID() AS [Current DB ID];
Current DB ID
---------------
5

Пример получения ID базы данных по имени.

SELECT DB_ID('master') AS [Master DB ID];
Master DB ID
--------------
1

Пример с несуществующей базой данных.

SELECT DB_ID('NonExistentDB') AS [NonExisting DB ID];
NonExisting DB ID
------------------
NULL

Использование в условии WHERE для проверки существования.

IF DB_ID('TestDB') IS NOT NULL
    PRINT 'База данных существует.'
ELSE
    PRINT 'База данных не существует.';
База данных не существует.

Похожие функции в MS SQL

DB_NAME: Эта функция выполняет обратную операцию. Она принимает идентификатор базы данных (database_id) и возвращает ее имя. Часто используется вместе с DB_ID.

OBJECT_ID: Возвращает идентификатор объекта (таблицы, представления, процедуры) в пределах указанной базы данных. В то время как DB_ID работает на уровне баз данных, OBJECT_ID работает на уровне объектов схемы.

Системное представление sys.databases: Предоставляет более полную информацию о всех базах данных на экземпляре, включая идентификатор, имя, состояние и другие свойства. Запрос SELECT database_id FROM sys.databases WHERE name = 'имя_базы' является альтернативой функции DB_ID.

Предпочтения в использовании: Функция DB_ID удобна для кратких проверок и встроенных вызовов. Для получения комплексной информации о базе данных предпочтительнее использовать представление sys.databases. Функция OBJECT_ID применяется для работы с объектами внутри конкретной базы.

Альтернативы в других СУБД

MySQL: Прямого аналога функции DB_ID не существует. Идентификатор базы данных как отдельная сущность обычно не используется. Для получения информации о текущей базе данных применяется функция DATABASE(), которая возвращает ее имя.

SELECT DATABASE();
DATABASE()
-----------
test_schema

Oracle: В Oracle концепция идентификатора базы данных отличается. Для получения ID текущего экземпляра (не базы данных в понимании SQL Server) можно запросить из представления V$DATABASE. Аналогом по смыслу (получение текущего контекста) может быть запрос к SYS_CONTEXT('USERENV', 'DB_NAME') для имени.

SELECT DBID FROM V$DATABASE;
      DBID
----------
 123456789

PostgreSQL: Как и в MySQL, база данных не имеет числового ID в том же смысле. Для получения идентификатора объекта базы данных (OID) можно использовать функцию oid из системного каталога pg_database.

SELECT oid FROM pg_database WHERE datname = 'postgres';
 oid
-----
 13578

SQLite: В SQLite отсутствуют понятия системных идентификаторов баз данных, так как обычно работа ведется с одним файлом-базой. Нет встроенной функции для этого.

Sybase ASE: Имеет функцию db_id(), которая аналогична по поведению функции в SQL Server, что связано с их общей историей развития.

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

Основная ошибка - предположение, что функция всегда возвращает числовое значение, без учета случая с несуществующей базой. Если не обработать NULL, это может привести к ошибкам в логике скриптов.

DECLARE @dbId INT = DB_ID('RandomDBName');
PRINT 'Идентификатор базы: ' + CAST(@dbId AS VARCHAR); -- Ошибка преобразования NULL в строку
Msg 245, Level 16, State 1, Line 2
Conversion failed when converting the varchar value 'Идентификатор базы: ' to data type int.

Правильный подход - проверка на NULL.

DECLARE @dbId INT = DB_ID('RandomDBName');
IF @dbId IS NOT NULL
    PRINT 'Идентификатор базы: ' + CAST(@dbId AS VARCHAR);
ELSE
    PRINT 'База не найдена.';
База не найдена.

Другая возможная проблема - использование имени базы данных в неправильном регистре или с лишними пробелами при чувствительных настройках сортировки (collation).

Изменения в последних версиях

Поведение функции DB_ID остается стабильным и неизменным в последних основных версиях SQL Server (2012, 2014, 2016, 2017, 2019, 2022). Сигнатура функции и ее основные характеристики не претерпели модификаций.

Единственный нюанс, на который стоит обратить внимание, связан с появлением новых системных баз данных, таких как msdb или tempdb, в ранних версиях, но их идентификаторы также фиксированы. Важно отметить, что в Управляемый экземпляр SQL Azure или Azure SQL Database функция также полностью поддерживается, но ее контекст применения ограничен, так как пользователь обычно работает только с одной пользовательской базой данных.

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

Использование в динамическом SQL для создания запроса к определенной базе данных по имени.

Пример sql
DECLARE @DbName sysname = 'AdventureWorks';
DECLARE @Sql nvarchar(MAX);
IF DB_ID(@DbName) IS NOT NULL
BEGIN
    SET @Sql = N'USE ' + QUOTENAME(@DbName) + ';
    SELECT COUNT(*) AS TableCount FROM sys.tables;';
    EXEC sp_executesql @Sql;
END
ELSE
    PRINT 'Указанная база данных отсутствует.';

Сравнение идентификаторов для определения, является ли база данных текущей.

Пример sql
IF DB_ID() = DB_ID('tempdb')
    PRINT 'Текущая база данных - tempdb.'
ELSE
    PRINT 'Текущая база данных - не tempdb.';
Текущая база данных - не tempdb.

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

Пример sql
SELECT
    name AS DatabaseName,
    database_id AS [ID from sys.databases],
    DB_ID(name) AS [ID from DB_ID()]
FROM sys.databases
ORDER BY database_id;
DatabaseName           ID from sys.databases  ID from DB_ID()
---------------------- ---------------------- ---------------
master                1                      1
tempdb                2                      2
model                 3                      3
msdb                  4                      4
TestDB                5                      5

Применение в функции безопасности для проверки контекста базы данных.

Пример sql
CREATE FUNCTION dbo.CheckIfSystemDB()
RETURNS BIT
AS
BEGIN
    DECLARE @CurrDBId smallint = DB_ID();
    IF @CurrDBId IN (DB_ID('master'), DB_ID('msdb'), DB_ID('model'))
        RETURN 1;
    RETURN 0;
END;

Использование в триггере уровня сервера (DDL) для получения имени базы, в которой произошло событие.

Пример sql
CREATE TRIGGER AuditDBChanges
ON ALL SERVER
AFTER CREATE_DATABASE, DROP_DATABASE
AS
BEGIN
    DECLARE @EventData xml = EVENTDATA();
    DECLARE @DbName sysname = @EventData.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'sysname');
    DECLARE @DbId smallint = DB_ID(@DbName); -- Может быть NULL для DROP!
    INSERT INTO master.dbo.AuditLog (EventType, DbName, DbId, EventTime)
    VALUES (@EventData.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'),
            @DbName,
            @DbId,
            GETDATE());
END;

MS SQL DB_ID function comments

En
DB ID Returns the database identification (ID) number