Sp dropmessage: примеры (SQL)

Функция sp_dropmessage для управления ошибками в SQL Server
Раздел: Функции изменения метаданных, Сообщения
sp_dropmessage: int

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

Системная хранимая процедура sp_dropmessage удаляет определенное пользовательское сообщение об ошибке из экземпляра Microsoft SQL Server. Сообщения добавляются с помощью процедуры sp_addmessage. Удалять можно только сообщения с кодом больше 50000, так как коды ниже зарезервированы для системных ошибок SQL Server.

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

Аргументы:

  • @msgnum (обязательный) - целочисленное значение (int). Код удаляемого пользовательского сообщения. Должен быть >= 50001.
  • @lang (необязательный) - строка (sysname). Определяет язык, для которого удаляется сообщение. Если параметр не указан, процедура удаляет сообщение для языка по умолчанию сессии. Если указано значение 'all', удаляются все языковые версии сообщения.
  • @msg_id (необязательный, выходной) - целочисленное значение (int). Выходной параметр, возвращающий идентификатор пользовательского сообщения. Обычно равен переданному значению @msgnum. Может использоваться для проверки.

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

Процедура возвращает 0 при успешном завершении и 1 при возникновении ошибки. Основные результаты выполнения также можно проверить с помощью глобальной функции @@ERROR или конструкции TRY...CATCH.

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

Пример 1: Удаление сообщения для языка по умолчанию

EXEC sp_dropmessage @msgnum = 50001;
(1 row affected)

Пример 2: Удаление сообщения для конкретного языка с выводом идентификатора

DECLARE @msg_id int;
EXEC sp_dropmessage @msgnum = 50002, @lang = 'Russian', @msg_id = @msg_id OUTPUT;
SELECT @msg_id AS 'Deleted Message ID';
Deleted Message ID
------------------
50002

Пример 3: Удаление всех языковых версий сообщения

EXEC sp_dropmessage @msgnum = 50003, @lang = 'all';
(2 rows affected)

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

Прямых аналогов для удаления сообщений не существует. Работа с пользовательскими ошибками реализована через набор системных процедур:

  • sp_addmessage - добавляет новое пользовательское сообщение. Используется для создания ошибок перед их применением в коде.
  • sp_altermessage - изменяет атрибуты существующего пользовательского сообщения, например, делает запись в журнал событий Windows.
  • RAISERROR / THROW - операторы для генерации ошибок, в том числе с использованием пользовательских сообщений, созданных через sp_addmessage.

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

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

Концепция системных таблиц или словарей данных для хранения сообщений об ошибках распространена, но реализация отличается.

Oracle: Пользовательские исключения объявляются в коде PL/SQL. Отдельного хранилища сообщений нет. Удаление связано с изменением кода пакета или процедуры.

-- Объявление исключения
my_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(my_exception, -20001);
-- Удаление - это удаление или комментирование этого кода.

PostgreSQL: Используются исключения в стиле PL/pgSQL. Сообщения задаются непосредственно при вызове. Аналога централизованного хранилища нет.

RAISE EXCEPTION 'Мое сообщение об ошибке' USING ERRCODE = 'UE001';

MySQL: Сигналы (SIGNAL) позволяют генерировать пользовательские ошибки с динамическим текстом. Постоянного хранилища сообщений также нет.

SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Пользовательская ошибка';

В отличие от MS SQL, в перечисленных СУБД нет необходимости в отдельной процедуре для удаления сообщения, так как сообщение является частью кода, а не отдельным объектом метаданных.

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

Ошибка 1: Попытка удалить несуществующее сообщение.

EXEC sp_dropmessage @msgnum = 99999;
Msg 15100, Level 16, State 1, Procedure sp_dropmessage, Line 60
The message 99999, language '<>', does not exist.
If the message is for a specific language, specify the language.

Ошибка 2: Попытка удалить системное сообщение (с кодом меньше 50001).

EXEC sp_dropmessage @msgnum = 101;
Msg 15100, Level 16, State 1, Procedure sp_dropmessage, Line 60
The message 101, language '<>', does not exist.
If the message is for a specific language, specify the language.

Ошибка 3: Ошибка из-за существующих зависимостей (если сообщение используется в активной конфигурации). На практике, sp_dropmessage редко вызывает такие ошибки, так как сообщения - это метаданные, на которые обычно нет жестких ссылок.

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

В SQL Server 2012 появился оператор THROW, который рекомендуется для вызова пользовательских ошибок вместо RAISERROR. Однако это не повлияло напрямую на функциональность sp_dropmessage. Основная логика процедуры остается неизменной с более ранних версий.

В последних версиях SQL Server (2017, 2019, 2022) значимых изменений в аргументах или поведении процедуры sp_dropmessage не было.

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

Пример 1: Безопасное удаление с проверкой существования.

Пример sql
DECLARE @msg_num INT = 50005;
IF EXISTS (SELECT * FROM sys.messages WHERE message_id = @msg_num AND language_id = 1033)
BEGIN
    PRINT 'Сообщение найдено. Удаление...';
    EXEC sp_dropmessage @msgnum = @msg_num, @lang = 'us_english';
    PRINT 'Сообщение удалено.';
END
ELSE
    PRINT 'Сообщение с кодом ' + CAST(@msg_num AS VARCHAR) + ' не найдено для указанного языка.';
Сообщение найдено. Удаление...
(1 row affected)
Сообщение удалено.

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

Пример sql
DECLARE @msg_id INT;
DECLARE msg_cursor CURSOR FOR
    SELECT message_id FROM sys.messages WHERE message_id >= 500000 AND language_id = 1033;
OPEN msg_cursor;
FETCH NEXT FROM msg_cursor INTO @msg_id;
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC sp_dropmessage @msgnum = @msg_id, @lang = 'us_english';
    PRINT 'Удалено сообщение: ' + CAST(@msg_id AS VARCHAR);
    FETCH NEXT FROM msg_cursor INTO @msg_id;
END;
CLOSE msg_cursor;
DEALLOCATE msg_cursor;
Удалено сообщение: 500001
(1 row affected)
Удалено сообщение: 500002
(1 row affected)

Пример 3: Использование в блоке обработки ошибок для очистки метаданных при пересоздании сообщения.

Пример sql
BEGIN TRY
    EXEC sp_dropmessage @msgnum = 70001, @lang = 'all';
END TRY
BEGIN CATCH
    PRINT 'Не удалось удалить старое сообщение. Возможно, оно не существует.';
END CATCH
GO
-- Теперь можно безопасно добавить сообщение с обновленным текстом
EXEC sp_addmessage @msgnum = 70001, @severity = 16,
    @msgtext = 'Обновленный текст ошибки: недопустимая сумма.',
    @lang = 'Russian';
(1 row affected)

MS SQL sp_dropmessage function comments

En
Sp dropmessage Drops a user-defined error message