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

Создание пользовательских сообщений в SQL Server через sp_addmessage
Раздел: Функции изменения метаданных, Сообщения
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, процедура сохраняет обратную совместимость со всеми предыдущими версиями.

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

Создание многоязычных сообщений об ошибках:

Пример sql
-- Английская версия
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 добавлено.

Использование сообщения в триггере с параметрами:

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

Создание сообщения с уровнем серьезности, требующим немедленного закрытия соединения:

Пример sql
EXEC sp_addmessage @msgnum = 50020, @severity = 20, @msgtext = 'Критическая ошибка базы данных', @with_log = 'TRUE';
GO

Использование с инструкцией THROW:

Пример sql
-- Создание сообщения
EXEC sp_addmessage @msgnum = 50025, @severity = 16, @msgtext = 'Операция не может быть выполнена: %s';
GO

-- Использование в коде
BEGIN TRY
  THROW 50025, 'недостаточно прав', 1;
END TRY
BEGIN CATCH
  PRINT ERROR_MESSAGE();
END CATCH
Операция не может быть выполнена: недостаточно прав

Создание информационного сообщения (низкий уровень серьезности):

Пример sql
EXEC sp_addmessage @msgnum = 50030, @severity = 1, @msgtext = 'Информация: %s';
GO

RAISERROR (50030, 1, 1, 'Загрузка данных завершена') WITH NOWAIT;

MS SQL sp_addmessage function comments

En
Sp addmessage Adds a new user-defined error message to an instance of SQL Server