SQL Server 2000: Hoe verlaat ik een opgeslagen procedure?

Hoe kan ik het midden van een opgeslagen procedure afsluiten?

Ik heb een opgeslagen procedure waar ik vroeg uit wil komen (terwijl ik probeer deze te debuggen). Ik heb geprobeerd RETURNen raiserrorte bellen, en de sp blijft draaien:

CREATE PROCEDURE dbo.Archive_Session @SessionGUID uniqueidentifier AS
    print 'before raiserror'
    raiserror('this is a raised error', 18, 1)
    print 'before return'
    return -1
    print 'after return'
[snip]

Ik weet dat het blijft werken omdat ik verderop een fout tegenkom. Ik zie geen van mijn afdrukken. Als ik commentaar geef op het grootste deel van de opgeslagen procedure:

CREATE PROCEDURE dbo.Archive_Session @SessionGUID uniqueidentifier AS
    print 'before raiserror'
    raiserror('this is a raised error', 18, 1)
    print 'before return'
    return -1
    print 'after return'
   /*
     [snip]
   */

Dan krijg ik mijn foutmelding niet en zie ik de resultaten:

before raiserror
Server: Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 5
this is a raised error
before return

Dus de vraag is: hoe kom ik uit een opgeslagen procedure in SQL Server?


Antwoord 1, autoriteit 100%

U kunt RETURNgebruiken om de uitvoering van een opgeslagen procedure onmiddellijk te stoppen. Citaat overgenomen van Books Online:

Verlaat onvoorwaardelijk een zoekopdracht of
procedure. RETOUR is onmiddellijk en
compleet en kan op elk moment worden gebruikt
om een ​​procedure, batch of te verlaten
statement blok. Verklaringen die
follow RETURN worden niet uitgevoerd.

Uit paranoia heb ik uw voorbeeld geprobeerd en het voert de PRINTs uit en stopt de uitvoering onmiddellijk.


Antwoord 2, autoriteit 32%

Tenzij u een ernst van 20 of hoger opgeeft, zal raiserrorde uitvoering niet stoppen. Zie de MSDN-documentatie.

De normale oplossing is om een ​​returnop te nemen na elke raiserror:

if @whoops = 1
    begin
    raiserror('Whoops!', 18, 1)
    return -1
    end

Antwoord 3, autoriteit 13%

Zet het in een TRY/CATCH.

Wanneer RAISERROR wordt uitgevoerd met een ernst
van 11 of hoger in een TRY-blok, it
draagt ​​de controle over aan de bijbehorende
CATCH-blok

Referentie: MSDN.

EDIT:dit werkt voor MSSQL 2005+, maar ik zie dat je nu duidelijk hebt gemaakt dat je aan MSSQL 2000 werkt. Ik laat dit hier ter referentie achter.


Antwoord 4, autoriteit 4%

Dit werkt hier.

ALTER PROCEDURE dbo.Archive_Session
    @SessionGUID int
AS 
    BEGIN
        SET NOCOUNT ON
        PRINT 'before raiserror'
        RAISERROR('this is a raised error', 18, 1)
        IF @@Error != 0 
            RETURN
        PRINT 'before return'
        RETURN -1
        PRINT 'after return'
    END
go
EXECUTE dbo.Archive_Session @SessionGUID = 1

Retourneren

before raiserror
Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 7
this is a raised error

Antwoord 5, autoriteit 4%

Dit lijkt veel code, maar de beste manier die ik heb gevonden om het te doen.

   ALTER PROCEDURE Procedure
    AS
    BEGIN TRY
        EXEC AnotherProcedure
    END TRY
    BEGIN CATCH
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorSeverity INT;
        DECLARE @ErrorState INT;
        SELECT 
            @ErrorMessage = ERROR_MESSAGE(),
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE();
        RAISERROR (@ErrorMessage, -- Message text.
                   @ErrorSeverity, -- Severity.
                   @ErrorState -- State.
                   );
        RETURN --this forces it out
    END CATCH
--Stuff here that you do not want to execute if the above failed.    
    END --end procedure

Antwoord 6

Het komt omdat je geen BEGINen ENDstatements hebt. U zou de afdrukken of fouten bij het uitvoeren van deze verklaring niet moeten zien, alleen Statement Completed(of iets dergelijks).

Other episodes