В SQL Server существует несколько способов вызова пользовательских ошибок из хранимых процедур, каждый со своими особенностями и вариантами использования.
CREATE PROCEDURE dbo.ValidateOrder
@OrderID INT
AS
BEGIN
IF NOT EXISTS (SELECT 1 FROM Orders WHERE OrderID = @OrderID)
BEGIN
RAISERROR('Order with ID %d does not exist', 16, 1, @OrderID)
RETURN -1
END
-- Основная логика процедуры
END
Параметры:
Особенности:
CREATE PROCEDURE dbo.ProcessPayment
@Amount DECIMAL(18,2)
AS
BEGIN
IF @Amount <= 0
BEGIN
THROW 50001, 'Payment amount must be positive', 1;
END
-- Основная логика процедуры
END
Параметры:
Преимущества:
-- Добавление пользовательского сообщения
EXEC sp_addmessage
@msgnum = 50002,
@severity = 16,
@msgtext = 'Invalid customer status: %s',
@lang = 'us_english';
-- Использование в процедуре
CREATE PROCEDURE dbo.ValidateCustomer
@Status VARCHAR(20)
AS
BEGIN
IF @Status NOT IN ('Active', 'Pending', 'Inactive')
BEGIN
RAISERROR(50002, 16, 1, @Status)
RETURN
END
END
CREATE PROCEDURE dbo.CheckInventory
@ProductID INT
AS
BEGIN
IF NOT EXISTS (SELECT 1 FROM Products WHERE ProductID = @ProductID)
RETURN 1 -- Код ошибки
DECLARE @Qty INT = (SELECT Quantity FROM Inventory WHERE ProductID = @ProductID)
IF @Qty <= 0
RETURN 2 -- Другой код ошибки
-- Успешное выполнение
RETURN 0
END
Уровень | Значение | Поведение |
---|---|---|
0-10 | Информационные сообщения | Не прерывает выполнение |
11-16 | Пользовательские ошибки | Прерывает пакет (для THROW) |
17-19 | Серьезные системные ошибки | Прерывает соединение |
20+ | Фатальные ошибки системы | Прерывает процесс SQL Server |
CREATE PROCEDURE dbo.ProcessOrder
@OrderID INT
AS
BEGIN
BEGIN TRY
-- Логика обработки заказа
END TRY
BEGIN CATCH
INSERT INTO ErrorLog(ErrorNumber, ErrorMessage, ProcedureName)
VALUES (ERROR_NUMBER(), ERROR_MESSAGE(), 'ProcessOrder')
THROW; -- Повторно вызываем ошибку
END CATCH
END
CREATE PROCEDURE dbo.TransferFunds
@FromAccount INT,
@ToAccount INT,
@Amount DECIMAL(18,2)
AS
BEGIN
SET XACT_ABORT ON; -- Автоматический ROLLBACK при ошибке
BEGIN TRANSACTION;
-- Логика перевода
IF @Amount <= 0
THROW 50003, 'Amount must be positive', 1;
COMMIT;
END
Резюмируем: Для вызова пользовательских ошибок в SQL Server предпочтительно использовать THROW для простых случаев и sp_addmessage для стандартизированных сообщений. Всегда учитывайте уровень серьезности ошибки и её влияние на транзакции. Для комплексной обработки ошибок сочетайте TRY/CATCH блоки с логированием и соответствующими кодами возврата.