2016-12-09 1 views
0

Хорошо, я буквально лысаю от того, чтобы потянуть мои волосы сейчас! Почти 10 часов тратили на это, но не могли понять. Я пытаюсь написать хранимую процедуру T-SQL для удаления записей из 2 таблиц, соответствующих входным данным, и распечатать сообщение, если удаление было успешным, и зафиксировать транзакцию, а если нет записей, откатите транзакцию и обработайте ошибки, используя Попробуй поймать. Я написал код ниже, но проблема в том, что даже если данные не совпадают с вводом, я все равно получаю «Command (s)» успешно завершен ». сообщение! Я ценю вашу помощь, чтобы исправить мою ошибку. До сих пор мой код выглядит следующим образом:Удалить Неиспользуемые записи Из таблицы в Хранимой процедуре с помощью Try Catch показ завершен успешно

Use Northwind 
Go 

Create Procedure uspDeleteOrder 
@orderID int As 
Set nocount on  
If Exists (Select * from Orders Where OrderID = @orderID) 
Begin Try 
    Begin Transaction 
     Delete From dbo.[Order Details] 
     Where dbo.[Order Details].OrderID = @orderID  
     Delete From Orders 
     Where OrderID = @orderID 
    COMMIT TRANSACTION 
    Print 'The article has been deleted!' 
End Try 
Begin Catch 
    IF (@@trancount > 0) 
    Begin   
     ROLLBACK TRANSACTION 
    End 
PRINT '*************Error Detail****************' 
PRINT 'Error Number :' + CAST(ERROR_NUMBER() AS VARCHAR) 
PRINT 'Error Severity:' + CAST(ERROR_SEVERITY() AS VARCHAR) 
PRINT 'Error State :' + CAST(ERROR_STATE() AS VARCHAR) 
PRINT 'Error Line :' + CAST(ERROR_LINE() AS VARCHAR) 
PRINT 'Error Message :' + ERROR_MESSAGE() 
End Catch 

Exec uspDeleteOrder 11077 

UPDATE: Хорошо, я редактировал свой код к этому, я думаю, в значительной степени делает работу, но я не уверен, что это правильный способ сделать это:

Create Procedure uspDeleteOrder 
@orderID int As 
Set nocount on  
If Exists (Select * from Orders Where OrderID = @orderID) 
Begin 
    Begin Try 
     Begin Transaction 
      Delete From dbo.[Order Details] 
      Where dbo.[Order Details].OrderID = @orderID  
      Delete From Orders 
      Where OrderID = @orderID 
     COMMIT TRANSACTION 
     Print 'The Order has been deleted!' 
     return 
    End Try 
    Begin Catch 
     IF (@@trancount > 0) 
     Begin   
      ROLLBACK TRANSACTION 
      RAISERROR ('Error', 16,1); 
     End 
     PRINT '*************Error Detail****************' 
     PRINT 'Error Number :' + CAST(ERROR_NUMBER() AS VARCHAR) 
     PRINT 'Error Severity:' + CAST(ERROR_SEVERITY() AS VARCHAR) 
     PRINT 'Error State :' + CAST(ERROR_STATE() AS VARCHAR) 
     PRINT 'Error Line :' + CAST(ERROR_LINE() AS VARCHAR) 
     PRINT 'Error Message :' + ERROR_MESSAGE() 
    End Catch 
End 
Else 
Begin 
    RAISERROR ('No Order ID', 16,1); 
End 

Любые мнения?

+0

Попробуйте добавить 'return' в конце блока' try'. – FDavidov

+2

Кстати, DELETE с условиями всегда будет успешным, даже если для удаления не найдено совпадающих записей. – FDavidov

+0

@FDavidov вы имеете в виду первый блок Try? как это помогает? Я добавил возврат до конца, но не сделал разницы. –

ответ

0

Вам необходимо RAISERROR изнутри Catch Block.

В настоящий момент вы обнаруживаете ошибку и выбираете данные об ошибке, но хранимая процедура по-прежнему возвращает успех.

Добавить линию

RAISERROR ('Err', 16,1); 

к блоку поймать

+0

Незначительная точка, но MS рекомендует [бросить] (https://msdn.microsoft.com/en-us/library/ee677615.aspx), за повышение ошибки, для новых разработок. [Источник] (https://msdn.microsoft.com/en-us/library/ms178592.aspx?f=255&MSPPError=-2147217396). –

0

Так что, если там, где нет Детали_Заказов не будут удалены вы хотите напечатать это? Вы можете сделать это, как в этом примере ниже. Легко изменить, чтобы выбросить исключение вместо печати или что-то, что вам нужно

Также почему заявление возврата?

Create Procedure uspDeleteOrder 
@orderID int As 

Set nocount on  

declare @DeleteOrderDetailCount int 

If Exists (Select * from Orders Where OrderID = @orderID) 
Begin 
    Begin Try 
     Begin Transaction 
      Delete From dbo.[Order Details] 
      Where dbo.[Order Details].OrderID = @orderID  

      select @DeleteOrderDetailCount = @@ROWCOUNT 

      Delete From Orders 
      Where OrderID = @orderID 

     COMMIT TRANSACTION 

     if @DeleteOrderDetailCount = 0 
     begin 
      Print 'There where no orders details to delete' 
     end 

     Print 'The Order has been deleted!' 

     -- why a return here ???? 
     -- return 
    End Try 
    Begin Catch 
     IF (@@trancount > 0) 
     Begin   
      ROLLBACK TRANSACTION 
      RAISERROR ('Error', 16,1); 
     End 
     PRINT '*************Error Detail****************' 
     PRINT 'Error Number :' + CAST(ERROR_NUMBER() AS VARCHAR) 
     PRINT 'Error Severity:' + CAST(ERROR_SEVERITY() AS VARCHAR) 
     PRINT 'Error State :' + CAST(ERROR_STATE() AS VARCHAR) 
     PRINT 'Error Line :' + CAST(ERROR_LINE() AS VARCHAR) 
     PRINT 'Error Message :' + ERROR_MESSAGE() 
    End Catch 
End 
Else 
Begin 
    RAISERROR ('No Order ID', 16,1); 
End 
0

Вы пытались захватить строки, затронутые с @@ ROWCOUNT

DECLARE @v1 INT 
DELETE From dbo.[Order Details] 
Where dbo.[Order Details].OrderID = @orderID  
SET @v1 = @@ROWCOUNT 

Это позволит вам реализовать определенную логику для захвата нежелательных сценариев.