IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name = 'insert_orderline')
BEGIN
PRINT 'Dropping Procedure insert_orderline'
DROP PROCEDURE insert_orderline
END
GO
PRINT 'Creating Procedure insert_orderline'
GO
CREATE PROCEDURE insert_orderline
-- Add the parameters suppliedthe stored procedure here
@OrderLineID INT OUTPUT,
@OrderID INT,
@Price MONEY,
@ProductID INT,
@Qty FLOAT,
@DimensionID SMALLINT
AS
BEGIN
SET NOCOUNT ON
DECLARE @ProcName SYSNAME
SELECT @ProcName = OBJECT_NAME(@@PROCID)
IF (@OrderID IS NULL)
BEGIN
RAISERROR(N'%s: Invalid parameters supplied, @OrderID IS NULL', 11, 1, @ProcName)
RETURN(-100)
END
IF (@Price IS NULL)
BEGIN
RAISERROR(N'%s: Invalid parameters supplied, @Price IS NULL', 11, 1, @ProcName)
RETURN(-100)
END
IF (@ProductID IS NULL)
BEGIN
RAISERROR(N'%s: Invalid parameters supplied, @ProductID IS NULL', 11, 1, @ProcName)
RETURN(-100)
END
IF (@Qty IS NULL)
BEGIN
RAISERROR(N'%s: Invalid parameters supplied, @Qty IS NULL', 11, 1, @ProcName)
RETURN(-100)
END
IF (@DimensionID IS NULL)
BEGIN
RAISERROR(N'%s: Invalid parameters supplied, @DimensionID IS NULL', 11, 1, @ProcName)
RETURN(-100)
END
DECLARE @TranCount INT
DECLARE @TranName NVARCHAR(32)
SELECT @TranName = SUBSTRING(N'TR_' + @ProcName, 1, 32)
SELECT @TranCount = @@TRANCOUNT
IF (@TranCount = 0)
BEGIN TRAN @TranName
ELSE
SAVE TRAN @TranName
DECLARE @Error INT
SELECT @OrderLineID = NULL
SELECT @OrderID = [OrderID] FROM [dbo].[Order] WITH (HOLDLOCK) WHERE ([OrderID] = @OrderID)
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRAN @TranName
RAISERROR(N'%s: БД не містить замовлення з ідентифіктором @OrderID = %d', 11, 1, @ProcName, @OrderID)
RETURN(-1000)
END
SELECT @ProductID = [ProductID] FROM [dbo].[Product] WITH (HOLDLOCK) WHERE ([ProductID] = @ProductID)
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRAN @TranName
RAISERROR(N'%s: БД не містить товару з ідентифіктором @ProductID = %d', 11, 1, @ProcName, @ProductID)
RETURN(-2000)
END
SELECT @DimensionID = [DimensionID] FROM [dbo].[Dimension] WITH (HOLDLOCK) WHERE ([DimensionID] = @DimensionID)
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRAN @TranName
RAISERROR(N'%s: БД не містить одиниці з ідентифіктором DimensionID = %d', 11, 1, @ProcName, @DimensionID)
RETURN(-3000)
END
INSERT INTO [dbo].[OrderLine]([OrderID], [Price], [ProductID], [Qty], [DimensionID])
VALUES(@OrderID, @Price, @ProductID, @Qty, @DimensionID)
SELECT @Error=@@ERROR, @OrderLineID = @@IDENTITY
IF (@Error <> 0)
BEGIN
ROLLBACK TRAN @TranName
RAISERROR(N'%s: Оператор INSERT INTO [dbo].[OrderLine] зазнав невдачі', 11, 1, @ProcName)
RETURN(@Error)
END
IF (@TranCount = 0)
COMMIT TRAN @TranName
RETURN(0)
END
GO
GRANT EXEC ON insert_orderline TO PUBLIC
GO
...
C> IF (@OrderID IS NULL)
C> BEGIN
C> RAISERROR(N'%s: Invalid parameters supplied, @OrderID IS NULL', 11, 1, @ProcName)
C> RETURN(-100)
C> END
...
Достигается NOT NULL в таблице на соответсвующие поля.
C> SELECT @OrderID = [OrderID] FROM [dbo].[Order] WITH (HOLDLOCK) WHERE ([OrderID] = @OrderID)
C> IF (@@ROWCOUNT = 0)
C> BEGIN
C> ROLLBACK TRAN @TranName
C> RAISERROR(N'%s: БД не містить замовлення з ідентифіктором @OrderID = %d', 11, 1, @ProcName, @OrderID)
C> RETURN(-1000)
C> END
...
Достигается Foreign key в таблице, и далее можно парсить ошибки сервера, если нужны осмысленные сообщения
C>
таким образом текст процедуры сокращается раза в два...
Здравствуйте, chabster, Вы писали:
C>А расскажите подробнее как парсить ошибки сервера? Плюс учесть тот факт, что фреймворк бывает локализированным
Как-как... ловить exception религия не позволяет? Например в Delphi ADO компонентах есть помнится мне всякие обработчики OnError...
А локализация — точно также как и локализация всего остального приложения...
Все что можно сделать на сервере декларативно — лучше так и сделать... Будет быстрее и надежнее...
Здравствуйте, chabster, Вы писали:
C>.NET, текст исключения может быть на 10-ти языках — что прикажете делать? C>Кодов ошибок много, сложно....
Не понял постановки задачи...
Т.е. все сообщения об ошибках должны быть на английском языке? или на каком?
Вы писали:
C> IF (@TranCount = 0) C> BEGIN TRAN @TranName C> ELSE C> SAVE TRAN @TranName C> DECLARE @Error INT C> SELECT @OrderLineID = NULL C> SELECT @OrderID = [OrderID] FROM [dbo].[Order] WITH (HOLDLOCK) WHERE ([OrderID] = @OrderID)
[/code]
Зачем открывать транзакцию а потом делать select? Нельзя транзакцию открыть после селекта?
Хинт (HOLDLOCK) у Вас сколько пользователей должно работать с этой таблицей одновременно?
Если много, то не ожидаете проблем с производительностью?