2013-01-02 12 views
7

Witam Piszę procedurę przechowywaną, która będzie wykonywała partię zadań w harmonogramie godzinowym i próbuję zdecydować, czy zwrócić błędy lub je podnieść. Zakładając, że rejestrowałbym błędy w każdym zadaniu, które prowadziłyby do lepszej wydajności i łatwości konserwacji?t-sql Powrót Kody błędów vs RaiseError

np.

-with kody błędu

CREATE PROCEDURE Job1 
AS 
BEGIN 

    BEGIN TRY 
     --Do some work 
    END TRY 
    BEGIN CATCH 
     --log error 
     RETURN 1; --Return 1 for error 
    END CATCH 
    RETURN 0; 

END 

CREATE PROCEDURE USP_BatchJob 
AS 
BEGIN 
    BEGIN TRANSACTION; 

    DECLARE @Error INT; 
    EXEC @Error = Job1; 
    IF @Error <> 0 
     GOTO ErrorHandling; 

    EXEC @Error = Job1; 
    IF @Error <> 0 
     GOTO ErrorHandling; 

    IF @@TRANCOUNT > 0 
     COMMIT TRANSACTION; 

    RETURN; 

ErrorHandling: 
    IF @@TRANCOUNT > 0 
     ROLLBACK; 
END 

np RaiseError

CREATE PROCEDURE Job1 
AS 
BEGIN 

    BEGIN TRY 
     --Do some work 
    END TRY 
    BEGIN CATCH 
     --log error 
     RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), ERROR_STATE()); 
    END CATCH 

END 

CREATE PROCEDURE USP_BatchJob 
AS 
BEGIN 
    BEGIN TRANSACTION 
    BEGIN TRY 

    EXEC Job1; 

    EXEC Job1; 

    END TRY 
    BEGIN CATCH 
     IF @@TRANCOUNT > 0 
      ROLLBACK; 
    END CATCH 

    IF @@TRANCOUNT > 0 
     COMMIT TRANSACTION; 

END 

Ten ostatni wydaje się produkować kod bardziej linkujących

Odpowiedz

3

Będąc o styl kodowania, może to być problem religijny. Główną różnicą między kodem powrotu i wyjątkiem jest to, że wyjątek będzie nadal przekazywany do łańcucha wywołań.

Ogólnie w kodzie, który piszę, używam zwracanych wartości, aby zwrócić status procedury składowanej jako "błąd aplikacji". Podobnie jak w twoim przykładzie, 0 oznacza sukces, a cokolwiek innego oznacza porażkę. Ilekroć wywołuję procedurę przechowywaną w kodzie rzeczywistym, mam kontrolę wartości zwracanej, a także wszelkich nowych błędów, które mogą się pojawić. Nawiasem mówiąc, w SQL Server nie można sprawdzić, czy nie powiodło się z "@retval <> 0", ponieważ procedury przechowywane mogą zwracać NULL.

Oczywiście, błędy wyjątków/bazy danych mogą nadal występować. Chodzi o to, że po rozpoznaniu wyjątku jest on rejestrowany i obsługiwany. System "błąd" zamienia się w błąd aplikacji.

Jedną z napotkanych problemów jest interakcja z programem SQL Server Agent. W tym celu chcesz zgłosić błąd "rozwidlenia" do kroku obsługi błędów. Można to łatwo zrobić w ramach etapu zadania, patrząc na wartość zwracaną, a następnie generując błąd.

+0

* "... ponieważ procedury składowane mogą zwracać NULL" * - ta instrukcja wydaje się być niepoprawna. Sądząc po podręczniku [SQL Server 2000 RETURN] (http://msdn.microsoft.com/en-us/library/aa238375%28v=sql.80%29.aspx), a także w [SQL Server 2012 jeden ] (http://msdn.microsoft.com/en-us/library/ms174998%28v=sql.110%29.aspx), procedur przechowywanych w SQL Server nie można zwrócić NULL. –

+0

To jest rzeczywiście niepoprawne. Wypróbowałem to (SQL Server 2012) i otrzymałem: Procedura "ReturnNullTest" próbowała zwrócić status NULL, co nie jest dozwolone. Zamiast tego zostanie zwrócony status 0. Pozostała odpowiedź jest jednak bardzo pomocna. – Davos

+1

@ Davos. . . Frazowanie jest nieeleganckie. Procedury przechowywane nie zwracają 'NULL', ale jeśli procedura składowana nie powiedzie się, zwracana wartość wykryta przez wywołującego to' NULL'. Lub, jeśli procedura składowana nie ma instrukcji "return". –