Sp dropmessage: примеры (SQL)
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: Безопасное удаление с проверкой существования.
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: Удаление всех пользовательских сообщений для текущего языка.
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: Использование в блоке обработки ошибок для очистки метаданных при пересоздании сообщения.
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)