2017-05-15 3 views
3

Ich weiß, dass viele Entscheidungen darüber haben. Noch. Wenn ich eine Prozedur habe, dann möchte ich in vielen Fällen ein Ergebnis auswählen und die Prozedur beenden. Es ist gut GOTO Aussage zu verwenden, oder eine bessere Art und Weise (nicht klassisches if...else)SqlServer GOTO für Exit-Prozedur mit Select

Beispiel:

create procedure MyProc @Parm int 
as 
    declare @Result nvarchar(50) 

    set @Result = 'OK' 

    if @Parm = 1 begin 
     set @Result = 'Error Example 1' 
     goto ExitProc; 
    end 

    if @Parm = 2 begin 
     set @Result = 'Error Example 2' 
     goto ExitProc; 
    end 

    if @Parm = 3 begin 
     set @Result = 'Error Example 3' 
     goto ExitProc; 
    end 

    ect... 

    ExitProc: 

    select @Result as Result, 100 as P2 
    from Table1 
+2

goto ist nie eine gute Lösung. Es gibt viel darüber geschrieben und es wurde vor Jahrzehnten verboten. classical if..else ist die beste Lösung, was ist daran falsch? – GuidoG

Antwort

3

Whit Ihren echter Code komplexer als ein, wenn sonst Single zu sein (wie gesagt auf einem Kommentar), dann könnten Sie Ihre eigenen Ausnahmen auslösen, wenn Sie sie benötigen, zwingen die gespeicherte Prozedur zu beenden und informieren Sie Ihre Anwendung des Fehlers.

Beispiel:

create procedure MyProc @Parm int 
as 
    if @Parm = 1 begin 
     THROW 60001, 'Error Example 1', 1; 
    end 

    if @Parm = 2 begin 
     THROW 60001, 'Error Example 2', 2; 
    end 

    if @Parm = 3 begin 
     THROW 60001, 'Error Example 3', 3; 
    end 

    ... 

Jetzt ist Ihre Anwendung kann diese Ausnahmen von SQL Server geworfen fangen, als ob sie einen anderen SQL-Fehler waren.

Sie könnten sogar diese Fehler auf der gespeicherten Prozedur selbst fangen und behandeln, obwohl ich denke, dass sie auf Ihrer Anwendung zu fangen ist eleganter.

Beispiel der Fehler auf der gespeicherten Prozedur zu fangen:

create procedure MyProc @Parm int 
as 

    begin try 
     if @Parm = 1 begin 
     THROW 60001, 'Error Example 1', 1; 
     end 

     if @Parm = 2 begin 
     THROW 60001, 'Error Example 2', 2; 
     end 

     if @Parm = 3 begin 
     THROW 60001, 'Error Example 3', 3; 
     end 

     ... 
    end try 

    begin catch 
     select error_message() as Result, 100 as P2 
     from Table1 
    end catch 
+0

Sehr gute Idee. Vielen Dank. das ist akzeptabel? – inon

+1

Im catch-Block habe ich hinzugefügt: "set @@ Result = error_message()". Anstelle von "set @@ Result = '...'" In jedem if-Block – inon

+1

Ja, viel besser, weil Sie auch andere SQL-Fehler fangen, die passieren könnten (Referenzfehler, Division durch 0, ... ...), und Sie haben immer die richtige Beschreibung in error_message(). Ich werde die Antwort modifizieren. –

0

Sie CASE anstelle der GOTO verwenden können. wenn ... Struktur

CREATE PROCEDURE MyProc @Parm int AS 
    DECLARE @Result nvarchar(50) 

    SELECT 100 as P2, @Result = CASE @Parm 
         WHEN 1 THEN 'Error Example 1' 
         WHEN 2 THEN 'Error Example 2' 
         WHEN 2 THEN 'Error Example 3' 
         ELSE 'OK' 
        END