Sp addmessage: примеры (SQL)
sp_addmessage: intОсновные сведения о функции sp_addmessage
Системная хранимая процедура sp_addmessage в Microsoft SQL Server предназначена для создания новых пользовательских сообщений об ошибках, которые добавляются в системное представление sys.messages. Эти сообщения могут использоваться совместно с инструкцией RAISERROR или THROW для генерации пользовательских ошибок и предупреждений в приложениях и скриптах.
Процедура применяется в случаях, когда стандартных сообщений SQL Server недостаточно, и требуется определить собственные ошибки с уникальными номерами и текстом, переведенным на разные языки.
Аргументы процедуры:
- @msgnum (обязательный) - целое число, идентификатор сообщения. Для пользовательских сообщений должно быть больше или равно 50000.
- @severity (обязательный) - уровень серьезности ошибки от 1 до 25. Для пользовательских сообщений обычно используются уровни от 11 до 16.
- @msgtext (обязательный) - текст сообщения, который может содержать параметры в формате %d, %s и т.д.
- @lang (необязательный) - язык сообщения (например, 'us_english', 'Russian'). Если не указан, используется язык текущего сеанса.
- @with_log (необязательный) - может быть 'TRUE' или 'FALSE'. Если 'TRUE', ошибка записывается в журнал приложений Windows и журнал ошибок SQL Server при генерации.
- @replace (необязательный) - если указано 'replace', существующее сообщение с тем же номером и языком будет заменено.
Процедура не возвращает результирующий набор, но возвращает целочисленный код возврата 0 при успешном выполнении или 1 при возникновении ошибки.
Примеры базового использования
Создание простого пользовательского сообщения:
EXEC sp_addmessage @msgnum = 50001, @severity = 16, @msgtext = 'Ошибка валидации данных';
GOСообщение 50001 добавлено.
Создание сообщения с параметром и логированием:
EXEC sp_addmessage @msgnum = 50002, @severity = 16, @msgtext = 'Не удалось найти запись с ID: %d', @with_log = 'TRUE';
GOСообщение 50002 добавлено.
Создание сообщения на русском языке с заменой:
EXEC sp_addmessage @msgnum = 50003, @severity = 14, @msgtext = 'Предупреждение: превышено допустимое количество записей', @lang = 'Russian', @replace = 'replace';
GOСообщение 50003 добавлено.
Похожие функции в MS SQL Server
В MS SQL Server существуют альтернативные способы работы с ошибками:
- RAISERROR - генерирует ошибку, но не создает постоянное сообщение в sys.messages. Используется для немедленной генерации ошибки с указанным текстом или номером существующего сообщения.
- THROW - более современная инструкция, появившаяся в SQL Server 2012. Позволяет генерировать исключения с заданными параметрами. Для использования с пользовательскими номерами ошибок требует предварительного создания сообщения через sp_addmessage.
Рекомендации: sp_addmessage используется, когда сообщение об ошибке должно быть переиспользуемым и многоязычным. RAISERROR подходит для разовых ошибок. THROW предпочтителен в современном коде, так как совместим с конструкцией TRY...CATCH.
Аналоги в других СУБД и языках
В других системах управления базами данных существуют аналогичные механизмы:
Oracle - используется pragma EXCEPTION_INIT и пользовательские исключения:
DECLARE
my_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(my_exception, -20001);
BEGIN
RAISE my_exception;
EXCEPTION
WHEN my_exception THEN
DBMS_OUTPUT.PUT_LINE('Пользовательская ошибка');
END;Пользовательская ошибка
PostgreSQL - инструкция RAISE с различными уровнями:
RAISE EXCEPTION 'Ошибка валидации данных' USING ERRCODE = 'P0001';MySQL - использование SIGNAL и RESIGNAL:
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Пользовательская ошибка';SQLite - пользовательские ошибки реализуются через возврат кодов ошибок в приложении, так как встроенных механизмов нет.
Отличия от MS SQL: в других СУБД обычно нет отдельной системной процедуры для глобальной регистрации сообщений, ошибки определяются непосредственно в коде.
Типичные ошибки при использовании
Ошибка при попытке создать сообщение с номером менее 50000:
EXEC sp_addmessage @msgnum = 10001, @severity = 16, @msgtext = 'Текст ошибки';Msg 22001, Level 16, State 1 Пользовательские сообщения об ошибках должны иметь идентификатор, больший или равный 50000.
Попытка создать сообщение с уже существующим номером без параметра @replace:
EXEC sp_addmessage @msgnum = 50001, @severity = 16, @msgtext = 'Другое сообщение';Msg 15031, Level 16, State 1 Сообщение 50001 уже существует. Если вы хотите добавить сообщение на другом языке, укажите язык. Если вы хотите заменить существующее сообщение, используйте параметр @replace='replace'.
Некорректный уровень серьезности:
EXEC sp_addmessage @msgnum = 50004, @severity = 30, @msgtext = 'Текст ошибки';Msg 2734, Level 16, State 1 Недопустимое значение параметра @severity. Укажите значение от 1 до 25.
Изменения в последних версиях
В SQL Server 2012 была введена инструкция THROW, которая стала предпочтительным способом генерации исключений. Однако sp addmessage продолжает поддерживаться для создания сообщений, используемых THROW.
В SQL Server 2016 улучшена интеграция пользовательских сообщений с механизмом расширенных событий (Extended Events).
Начиная с SQL Server 2017, нет существенных изменений в работе sp_addmessage, процедура сохраняет обратную совместимость со всеми предыдущими версиями.
Расширенные примеры использования
Создание многоязычных сообщений об ошибках:
-- Английская версия
EXEC sp_addmessage @msgnum = 50010, @severity = 16, @msgtext = 'Invalid customer ID: %d';
GO
-- Русская версия того же сообщения
EXEC sp_addmessage @msgnum = 50010, @severity = 16, @msgtext = 'Некорректный идентификатор клиента: %d', @lang = 'Russian';
GOСообщение 50010 добавлено. Сообщение 50010 добавлено.
Использование сообщения в триггере с параметрами:
CREATE TRIGGER trg_check_salary
ON employees
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS (SELECT 1 FROM inserted WHERE salary > 100000)
BEGIN
RAISERROR (50002, 16, 1, (SELECT employee_id FROM inserted WHERE salary > 100000));
END
END;
GOСоздание сообщения с уровнем серьезности, требующим немедленного закрытия соединения:
EXEC sp_addmessage @msgnum = 50020, @severity = 20, @msgtext = 'Критическая ошибка базы данных', @with_log = 'TRUE';
GOИспользование с инструкцией THROW:
-- Создание сообщения
EXEC sp_addmessage @msgnum = 50025, @severity = 16, @msgtext = 'Операция не может быть выполнена: %s';
GO
-- Использование в коде
BEGIN TRY
THROW 50025, 'недостаточно прав', 1;
END TRY
BEGIN CATCH
PRINT ERROR_MESSAGE();
END CATCHОперация не может быть выполнена: недостаточно прав
Создание информационного сообщения (низкий уровень серьезности):
EXEC sp_addmessage @msgnum = 50030, @severity = 1, @msgtext = 'Информация: %s';
GO
RAISERROR (50030, 1, 1, 'Загрузка данных завершена') WITH NOWAIT;