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 RETURN
en raiserror
te 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 RETURN
gebruiken 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 raiserror
de uitvoering niet stoppen. Zie de MSDN-documentatie.
De normale oplossing is om een return
op 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 BEGIN
en END
statements hebt. U zou de afdrukken of fouten bij het uitvoeren van deze verklaring niet moeten zien, alleen Statement Completed
(of iets dergelijks).