Udostępnij za pośrednictwem


@@ Błędów

Funkcja systemu @@ błąd zwraca wartość 0, jeśli ostatnio Transact-SQL instrukcja wykonana pomyślnie; Jeśli instrukcja wygenerowany błąd, @@ błąd zwraca numer błędu.Zmienia wartość @@ błąd po zakończeniu każdej Transact-SQL instrukcja.

Ponieważ @@ błąd pobiera nową wartość podczas każdego Transact-SQL zakończeniu instrukcja, proces @@ błąd w jeden z dwóch sposobów:

  • Badanie lub @@ błędy natychmiast po Transact-SQL instrukcja.

  • Zapisz @@ błąd w całkowitą zmiennej natychmiast po Transact-SQL instrukcja zakończeniu.Wartość zmiennej można później.

Jeśli instrukcja generuje błąd nie jest w blok TRY TRY…Konstrukcja połowu, błąd @@ muszą być badane lub użyte w instrukcji natychmiast po instrukcji, który wygenerował błąd.Jeśli jest instrukcja generuje błąd w blok TRY, @@ błędu można badane lub używane w pierwszej instrukcji blok CATCH skojarzone.W zakres bloku CATCH funkcja ERROR_NUMBER można pobrać ten sam numer błędu zgłosiło błąd @@.ERROR_NUMBER ma tę zaletę, że jest dostępny dla wszystkich instrukcja w zakres połowu zablokować, dlatego @@ błąd zostanie zresetowany przez pierwszą instrukcją w bloku CATCH.

@@ Błąd resetowania instrukcja warunkowych, takich jak instrukcja Jeżeli.Jeśli w instrukcja IF, odwołania @@ błędu w polu Jeśli odwołanie @@ błąd inaczej bloków nie pobierze informacje o błędzie @@.W poniższym przykładzie @@ błąd resetowania, gdy i nie zwraca błąd numer odwołania w instrukcja wydruku.

DECLARE @ErrorVar INT

RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
    -- This PRINT statement prints 'Error = 0' because
    -- @@ERROR is reset in the IF statement above.
    PRINT N'Error = ' + CAST(@@ERROR AS NVARCHAR(8));
GO

Poniższy przykład zwraca oczekiwanych wyniki.

DECLARE @ErrorVar INT

RAISERROR(N'Message', 16, 1);
-- Save the error number before @@ERROR is reset by
-- the IF statement.
SET @ErrorVar = @@ERROR
IF @ErrorVar <> 0
-- This PRINT statement correctly prints 'Error = 50000'.
    PRINT N'Error = ' + CAST(@ErrorVar AS NVARCHAR(8));
GO

Jeśli chcesz odwołać @@ błąd i @@ ROWCOUNT po uruchomieniu oświadczenie musi się odwoływać w tej samej instrukcja.BŁĄD @@ i @@ ROWCOUNT są resetowane z każdym Transact-SQL instrukcja; Dlatego obie musi odwoływać się w tej samej instrukcja natychmiast po jednym testowanego.W poniższym przykładzie @@ ROWCOUNT będzie zawsze równa 0, ponieważ nie są odwołania do czasu, po został zresetowany przez pierwsze Drukuj instrukcja.

USE AdventureWorks2008R2;
GO
DELETE FROM HumanResources.JobCandidate
    WHERE JobCandidateID = 13;
-- This PRINT would successfully capture any error number.
PRINT N'Error = ' + CAST(@@ERROR AS NVARCHAR(8));
-- This PRINT will always print 'Rows Deleted = 0 because
-- the previous PRINT statement set @@ROWCOUNT to 0.
PRINT N'Rows Deleted = ' + CAST(@@ROWCOUNT AS NVARCHAR(8));
GO

Poniższy przykład zwraca oczekiwanych wyniki.

USE AdventureWorks2008R2;
GO
DECLARE @ErrorVar INT;
DECLARE @RowCountVar INT;

DELETE FROM HumanResources.JobCandidate
  WHERE JobCandidateID = 13;
-- Save @@ERROR and @@ROWCOUNT while they are both
-- still valid.
SELECT @ErrorVar = @@ERROR,
    @RowCountVar = @@ROWCOUNT;
IF (@ErrorVar <> 0)
    PRINT N'Error = ' + CAST(@ErrorVar AS NVARCHAR(8));
PRINT N'Rows Deleted = ' + CAST(@RowCountVar AS NVARCHAR(8));
GO

Błąd @@ jest wywoływane tylko dla błędów nie dla ostrzeżenia; instancje, procedury przechowywane i wyzwalacze nie można używać @@ błąd wykrywać ostrzeżenia, które wystąpiły.

Wspólne wykorzystanie @@ błąd w SQL Server 2000 i wcześniej wskazują powodzenie lub niepowodzenie procedura składowana.Zmienna typu Liczba całkowita jest zainicjowany na 0.Po każdym Transact-SQL zakończeniu instrukcja, błąd @@ badane jest 0 i jeśli nie 0, it jest przechowywana w zmiennej.Procedura zwraca następnie zmiennej instrukcja RETURN.Jeśli żadna z Transact-SQL instrukcji w procedurze wystąpił błąd, zmienna pozostaje na poziomie 0.Jeżeli jeden lub więcej instrukcji wygenerowany błąd, zmienna posiada numer ostatniego błędu.W poniższym przykładzie pokazano prostą procedura składowana z tę logikę.

USE AdventureWorks2008R2;
GO
IF EXISTS(SELECT name FROM sys.objects
          WHERE name = N'SampleProcedure')
    DROP PROCEDURE SampleProcedure;
GO
-- Create a procedure that takes one input parameter
-- and returns one output parameter and a return code.
CREATE PROCEDURE SampleProcedure @EmployeeIDParm INT,
    @MaxVacation INT OUTPUT
AS

    -- Declare and initialize a variable to hold @@ERROR.
    DECLARE @ErrorSave1 INT, @ErrorSave2 INT;
    SET @ErrorSave1 = 0;

    -- Do a SELECT using the input parameter.
    SELECT LoginID, NationalIDNumber, JobTitle
        FROM HumanResources.Employee
        WHERE BusinessEntityID = @EmployeeIDParm;

    -- Save @@ERROR value in first local variable.
    SET @ErrorSave1 = @@ERROR;

    -- Set a value in the output parameter.
    SELECT @MaxVacation = MAX(VacationHours)
        FROM HumanResources.Employee;

    -- Save @@ERROR value in second local variable. 
    SET @ErrorSave2 = @@ERROR;
    -- If second test variable contains non-zero value, 
    -- overwrite value in first local variable.
    IF (@ErrorSave2 <> 0) SET @ErrorSave1 = @ErrorSave2;

    -- Returns 0 if neither SELECT statement had
    -- an error; otherwise, returns the last error.
    RETURN @ErrorSave1;
GO
    
DECLARE @OutputParm INT;
DECLARE @ReturnCode INT;

EXEC @ReturnCode = SampleProcedure 13, @OutputParm OUTPUT;

PRINT N'OutputParm = ' + CAST(@OutputParm AS NVARCHAR(20));
PRINT N'ReturnCode = ' + CAST(@ReturnCode AS NVARCHAR(20));
GO

Błąd @@ vs.SPRÓBUJ...CATCH

Jako podstawowy sposób wykrywanie błędów za pomocą @@ błąd prowadzi do bardzo różnych stylów kodu obsługi błędów niż ten, który jest używany z TRY…CATCH konstrukcje.

  • @@ Błąd muszą być badane albo zapisane po każdym Transact-SQL instrukcja, ponieważ nie można przewidzieć deweloper w wcześniejsze oświadczenie, które może wygenerować błąd.To podwaja liczbę Transact-SQL instrukcji, które musi być kodowane do wykonania danego fragmentu logiki.

  • TRY…Konstrukcje POŁÓW jest znacznie prostsze.Blok Transact-SQL instrukcji jest ograniczone przez instrukcje SPRÓBUJ rozpocząć i END TRY, i następnie zapisywane jeden blok CATCH obsługi błędów, które może być generowane przez danego bloku instrukcji.

Poza blok CATCH @@ błąd jest tylko część Aparat baz danych Błąd dostępne w ramach partia, procedura składowana lub wyzwalacza, generowany jest błąd.Wszystkie pozostałe części błędu, takie jak jego ważności, stan i tekst wiadomości zawierających ciągi zastępcze (na przykład nazwy obiektu) zwracane są tylko do aplikacji, w którym mogą być przetworzone przy użyciu interfejsu API mechanizmy obsługi błędów.Jeśli błąd wywołuje blok CATCH, ERROR_LINE, ERROR_MESSAGE, ERROR_PROCEDURE, ERROR_NUMBER, ERROR_SEVERITY i ERROR_STATE mogą być używane funkcje systemowe.