Поругайте мой TSQL :)
От: chabster Украина chabster.blogspot.com
Дата: 31.03.06 07:13
Оценка:
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
Posted via RSDN NNTP Server 2.0
Re: Поругайте мой TSQL :)
От: DrDred Россия  
Дата: 31.03.06 07:34
Оценка:
Здравствуйте, chabster, Вы писали:

C>
...
 
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>


таким образом текст процедуры сокращается раза в два...
--
WBR, Alexander
Re[2]: Поругайте мой TSQL :)
От: chabster Украина chabster.blogspot.com
Дата: 31.03.06 07:52
Оценка:
А расскажите подробнее как парсить ошибки сервера? Плюс учесть тот факт, что фреймворк бывает локализированным
Posted via RSDN NNTP Server 2.0
Re[3]: Поругайте мой TSQL :)
От: DrDred Россия  
Дата: 31.03.06 08:53
Оценка:
Здравствуйте, chabster, Вы писали:

C>А расскажите подробнее как парсить ошибки сервера? Плюс учесть тот факт, что фреймворк бывает локализированным

Как-как... ловить exception религия не позволяет? Например в Delphi ADO компонентах есть помнится мне всякие обработчики OnError...
А локализация — точно также как и локализация всего остального приложения...

Все что можно сделать на сервере декларативно — лучше так и сделать... Будет быстрее и надежнее...
--
WBR, Alexander
Re[4]: Поругайте мой TSQL :)
От: chabster Украина chabster.blogspot.com
Дата: 31.03.06 09:06
Оценка:
.NET, текст исключения может быть на 10-ти языках — что прикажете делать?
Кодов ошибок много, сложно....
Posted via RSDN NNTP Server 2.0
Re: Поругайте мой TSQL :)
От: KGP http://kornilow.newmail.ru
Дата: 31.03.06 09:24
Оценка:
Здравствуйте, chabster, Вы писали:
...
C> DECLARE @TranCount INT
C> DECLARE @TranName NVARCHAR(32)
C> SELECT @TranName = SUBSTRING(N'TR_' + @ProcName, 1, 32)
C> SELECT @TranCount = @@TRANCOUNT
C> IF (@TranCount = 0)
C> BEGIN TRAN @TranName
C> ELSE
C> SAVE TRAN @TranName

...
C> IF (@TranCount = 0)
C> COMMIT TRAN @TranName

...
C>[/code]

А это к чему? Что это по Вашему делает?
Re[2]: Поругайте мой TSQL :)
От: chabster Украина chabster.blogspot.com
Дата: 31.03.06 09:30
Оценка:
Оно не помоему делает, оно в общем ДЕЛАЕТ
Posted via RSDN NNTP Server 2.0
Re[3]: Поругайте мой TSQL :)
От: KGP http://kornilow.newmail.ru
Дата: 31.03.06 10:10
Оценка:
Здравствуйте, chabster, Вы писали:

C>Оно не помоему делает, оно в общем ДЕЛАЕТ

А что оно делает?
Re[5]: Поругайте мой TSQL :)
От: DrDred Россия  
Дата: 31.03.06 11:00
Оценка:
Здравствуйте, chabster, Вы писали:

C>.NET, текст исключения может быть на 10-ти языках — что прикажете делать?

C>Кодов ошибок много, сложно....
Не понял постановки задачи...
Т.е. все сообщения об ошибках должны быть на английском языке? или на каком?
--
WBR, Alexander
Re: Поругайте мой TSQL :)
От: SOf  
Дата: 31.03.06 15:53
Оценка:
Здравствуйте, chabster,

Вы писали:

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) у Вас сколько пользователей должно работать с этой таблицей одновременно?
Если много, то не ожидаете проблем с производительностью?

Удачи,
SOf.
Re: еще 3 копейки...
От: SOf  
Дата: 31.03.06 16:07
Оценка:
C> IF (@TranCount = 0)
C> BEGIN TRAN @TranName
C> ELSE
C> SAVE TRAN @TranName
Зачем использовать вложенные транзакции?
На грабли с ними не наступали?

Локализованные сообщения из хранимой тоже как-то странно IMHO смотрятся.
Нельзя их на уровне клиента локализовывать?

Код
C> IF (@TranCount = 0)
C> COMMIT TRAN @TranName
вводит в заблуждение .. не сразу соображаешь что там один @.

Общее впечатление:
Хранимает делает 1 insert, а коду просто немеряно. Хотя конечно разработчик попытался застраховаться
от ошибок

Удачи,
SOf
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.