none
Case Cunstrukt RRS feed

  • Frage

  • Hallo und guten Morgen

    Was läuft in folgender Case Anendung falsch?

    Wenn ich bei der erstellung nur CASE Eintippe ist es schon rot unterlegt.

    Meine Versuche mit Set Case und SELECT Case auch

    Besten Dak für einen Tipp!

    mfg

    Peter

    ALTER Proc [dbo].[spcboWaremRebatt]
    @Rabattgruppe varchar(25)= null,
    @Lieferant int = 0
    
    AS
    
    Case 
    
    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
         LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 THEN
        Print 'Beide leer'
    
    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 THEN
       Print 'Rabatt voll Lieferant leer'
    
    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 THEN
    	Print 'Rabatt leer Lieferant voll'
    
    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 THEN
    	Print 'Beide voll'
    END
    
    


    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
         LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 THEN
        Print 'Beide leer'

    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 THEN
       Print 'Rabatt voll Lieferant leer'

    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 THEN
    Print 'Rabatt leer Lieferant voll'

    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 THEN
    Print 'Beide voll'
    END

    Samstag, 2. März 2019 08:06

Antworten

  • 1. Da du den Case nicht einer Variablen zuweist
    2. in einem Case kann man Ausdrücke verwenden, aber nur sog. scalare Subselects, also einen Select, der genau 1 Wert aus 1 Zeile liefert.

    Dies ist aber nicht deine Anforderung.

    Die Lösung sähe in deinem Fall eher so aus:
    Das Ergebnis eines Where-Ausdruckes muss "wahr" werden um Zeilen auszuwählen, also muss das Case-Ergebnis einen abfragbaren Wert ergeben.

    SELECT Warengruppennummer, Warengruppenbeschreibung From dbo.tblWarengruppe WHERE case when
    LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1
    and dbo.tblWarengruppe.Warengruppennummer In
    (SELECT dbo.tblProdukt.Warengruppe
    From dbo.tblProdukt

    ) then 1

    else 0 end = 1 ORDER BY dbo.tblWarengruppe.Warengruppenbeschreibung;

    Somit kannst du innerhalb der Whereklausel verschiedene Abfragen durchführen.
    Dies ist so natürlich nicht performant.
    Innerhalb der Prozedur gibt es jjedoch auch noch den "IF".

    https://docs.microsoft.com/de-de/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-2017

    Somit kannst du deinen Case-Ausdruck in einen IF-Ausdruck ändern:

    ALTER Proc [dbo].[spcboWaremRebatt]
    @RAbattgruppe varchar(25)= null,
    @Lieferant int = 0
    
    AS
    
    if 
    
      LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
      LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 
    
      SELECT
      Warengruppennummer,
      Warengruppenbeschreibung
      From dbo.tblWarengruppe
      WHERE dbo.tblWarengruppe.Warengruppennummer In
      (SELECT dbo.tblProdukt.Warengruppe
      From dbo.tblProdukt)
      ORDER BY dbo.tblWarengruppe.Warengruppenbeschreibung;
    
    else if
      LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
      LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 
    
      SELECT
      Warengruppennummer,
      Warengruppenbeschreibung
      From dbo.tblWarengruppe
      WHERE dbo.tblWarengruppe.Warengruppennummer In
      (SELECT dbo.tblProdukt.Warengruppe
      From dbo.tblProdukt
      WHERE dbo.tblProdukt.RAbattgruppe = @RAbattgruppe)
      ORDER BY dbo.tblWarengruppe.Warengruppenbeschreibung;
    
    else if
      LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 
    
      SELECT
      Warengruppennummer,
      Warengruppenbeschreibung
      From tblWarengruppe
      WHERE tblWarengruppe.Warengruppennummer In
      (SELECT tblProdukt.Warengruppe
      From tblProdukt)
      AND tblWarengruppe.Lieferant = @Lieferant
      ORDER BY tblWarengruppe.Warengruppenbeschreibung;
    
    else if 
       LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 
    
      SELECT
      Warengruppennummer,
      Warengruppenbeschreibung
      From dbo.tblWarengruppe
      WHERE dbo.tblWarengruppe.Warengruppennummer In
      (SELECT dbo.tblProdukt.Warengruppe
      From tblProdukt
      WHERE tblProdukt.RAbattgruppe = @RAbattgruppe
      AND dbo.tblWarengruppe.Lieferant = @Lieferant)
      ORDER BY tblWarengruppe.Warengruppenbeschreibung;
    
    
    
    IF gehört zur SQL-Prozedursprache, CASE gehört zur SQL-Ausführungssprache.
    • Als Antwort vorgeschlagen bfuerchau Montag, 4. März 2019 22:53
    • Als Antwort markiert Wakolbi Dienstag, 5. März 2019 15:50
    Samstag, 2. März 2019 16:27

Alle Antworten

  • Hi,

    selbst wenn das gehen würde (was es nicht tut): Was soll das bringen? Du musst um THEN Zweig eine Rückgabe bestimmen, kein PRINT ...

    Was genau soll denn da passieren? Wirklich eine PRINT Ausgabe bei den einzelnen Bedingungen? Falls ja, pack das in einzelne IF ... BEGIN ... END Statements.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Samstag, 2. März 2019 08:41
    Moderator
  • Case ist ein Ausdruck, der ein Ergebnis liefert.
    Was muss also mit dem Ergebnis gemacht werden?

    Bei einer Funktion wäre das z.B.:

    return case .... end;

    Oder du weist das Ergebnis eine Variablen zu, die als INOUT-Parameter der Prozedur deklariert ist:

    @rabattgruppe = case .... end;

    Oder verwendest es in einem SQL-Befehle an den Stellen, an denen ein Ausdruck erlaubt ist.

    Samstag, 2. März 2019 10:18
  • Hallo an Alle!

    Das man mein Problem besser versteht:Das ist mein erster Versuch mit SQL Server. Ich bitte jetzt schon um vergebung für meine dämlichen Fragen.

    Dieses Konstrukt ist in einer Prozdedur die ich für das suchen von Produkten verwende. Wenn Rabattgrupppe und Lieferant leer sind, werden alle Warengruppen angezeigt. Wenn in einen Der Felder ein wert ist, dann soll gefiltert werden. 

    Was ich nicht verstehe ist, wenn ich CASE in die leere Prozedur hineinschreibe, leuchtet schon case mit roten unterstrich.

    Zum bessern verständniss habe ich die Fertige Prozedur (die etwas länger ist) mitgesendet.

    Die Select Anweisungen funktionieren beim Aufruf alle.

    mfg

    Peter

    ALTER Proc [dbo].[spcboWaremRebatt]
    @RAbattgruppe varchar(25)= null,
    @Lieferant int = 0
    
    AS
    
    Case 
    
    When LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 Then
    
    SELECT
    Warengruppennummer,
    Warengruppenbeschreibung
    From dbo.tblWarengruppe
    WHERE dbo.tblWarengruppe.Warengruppennummer In
    (SELECT dbo.tblProdukt.Warengruppe
    From dbo.tblProdukt)
    ORDER BY dbo.tblWarengruppe.Warengruppenbeschreibung;
    
    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 THEN
    
    SELECT
    Warengruppennummer,
    Warengruppenbeschreibung
    From dbo.tblWarengruppe
    WHERE dbo.tblWarengruppe.Warengruppennummer In
    (SELECT dbo.tblProdukt.Warengruppe
    From dbo.tblProdukt
    WHERE dbo.tblProdukt.RAbattgruppe = @RAbattgruppe)
    ORDER BY dbo.tblWarengruppe.Warengruppenbeschreibung;
    
    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 THEN
    
    SELECT
    Warengruppennummer,
    Warengruppenbeschreibung
    From tblWarengruppe
    WHERE tblWarengruppe.Warengruppennummer In
    (SELECT tblProdukt.Warengruppe
    From tblProdukt)
    AND tblWarengruppe.Lieferant = @Lieferant
    ORDER BY tblWarengruppe.Warengruppenbeschreibung;
    
    WHEN LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 THEN
    
    SELECT
    Warengruppennummer,
    Warengruppenbeschreibung
    From dbo.tblWarengruppe
    WHERE dbo.tblWarengruppe.Warengruppennummer In
    (SELECT dbo.tblProdukt.Warengruppe
    From tblProdukt
    WHERE tblProdukt.RAbattgruppe = @RAbattgruppe
    AND dbo.tblWarengruppe.Lieferant = @Lieferant)
    ORDER BY tblWarengruppe.Warengruppenbeschreibung;
    
    END
    

     
    Samstag, 2. März 2019 13:44
  • 1. Da du den Case nicht einer Variablen zuweist
    2. in einem Case kann man Ausdrücke verwenden, aber nur sog. scalare Subselects, also einen Select, der genau 1 Wert aus 1 Zeile liefert.

    Dies ist aber nicht deine Anforderung.

    Die Lösung sähe in deinem Fall eher so aus:
    Das Ergebnis eines Where-Ausdruckes muss "wahr" werden um Zeilen auszuwählen, also muss das Case-Ergebnis einen abfragbaren Wert ergeben.

    SELECT Warengruppennummer, Warengruppenbeschreibung From dbo.tblWarengruppe WHERE case when
    LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1
    and dbo.tblWarengruppe.Warengruppennummer In
    (SELECT dbo.tblProdukt.Warengruppe
    From dbo.tblProdukt

    ) then 1

    else 0 end = 1 ORDER BY dbo.tblWarengruppe.Warengruppenbeschreibung;

    Somit kannst du innerhalb der Whereklausel verschiedene Abfragen durchführen.
    Dies ist so natürlich nicht performant.
    Innerhalb der Prozedur gibt es jjedoch auch noch den "IF".

    https://docs.microsoft.com/de-de/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-2017

    Somit kannst du deinen Case-Ausdruck in einen IF-Ausdruck ändern:

    ALTER Proc [dbo].[spcboWaremRebatt]
    @RAbattgruppe varchar(25)= null,
    @Lieferant int = 0
    
    AS
    
    if 
    
      LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
      LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 
    
      SELECT
      Warengruppennummer,
      Warengruppenbeschreibung
      From dbo.tblWarengruppe
      WHERE dbo.tblWarengruppe.Warengruppennummer In
      (SELECT dbo.tblProdukt.Warengruppe
      From dbo.tblProdukt)
      ORDER BY dbo.tblWarengruppe.Warengruppenbeschreibung;
    
    else if
      LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
      LEN(TRIM(ISNULL(@Lieferant, ''))) < 1 
    
      SELECT
      Warengruppennummer,
      Warengruppenbeschreibung
      From dbo.tblWarengruppe
      WHERE dbo.tblWarengruppe.Warengruppennummer In
      (SELECT dbo.tblProdukt.Warengruppe
      From dbo.tblProdukt
      WHERE dbo.tblProdukt.RAbattgruppe = @RAbattgruppe)
      ORDER BY dbo.tblWarengruppe.Warengruppenbeschreibung;
    
    else if
      LEN(TRIM(ISNULL(@Rabattgruppe, ''))) < 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 
    
      SELECT
      Warengruppennummer,
      Warengruppenbeschreibung
      From tblWarengruppe
      WHERE tblWarengruppe.Warengruppennummer In
      (SELECT tblProdukt.Warengruppe
      From tblProdukt)
      AND tblWarengruppe.Lieferant = @Lieferant
      ORDER BY tblWarengruppe.Warengruppenbeschreibung;
    
    else if 
       LEN(TRIM(ISNULL(@Rabattgruppe, ''))) > 1 AND 
       LEN(TRIM(ISNULL(@Lieferant, ''))) > 1 
    
      SELECT
      Warengruppennummer,
      Warengruppenbeschreibung
      From dbo.tblWarengruppe
      WHERE dbo.tblWarengruppe.Warengruppennummer In
      (SELECT dbo.tblProdukt.Warengruppe
      From tblProdukt
      WHERE tblProdukt.RAbattgruppe = @RAbattgruppe
      AND dbo.tblWarengruppe.Lieferant = @Lieferant)
      ORDER BY tblWarengruppe.Warengruppenbeschreibung;
    
    
    
    IF gehört zur SQL-Prozedursprache, CASE gehört zur SQL-Ausführungssprache.
    • Als Antwort vorgeschlagen bfuerchau Montag, 4. März 2019 22:53
    • Als Antwort markiert Wakolbi Dienstag, 5. März 2019 15:50
    Samstag, 2. März 2019 16:27
  • Hallo!

    Vielen vielen Vielen Dank!!!

    Es funktioniert!!!

    Bei meiner vorhandenen Lektüre steht das If und Else if in SQL Server nicht beinhaltet ist. Somit   habe ich nicht den Versuch unternommen. (Ich hätte mir 4 Tage erspart)

    Nochmals besten Dank

    Peter

     

    Montag, 4. März 2019 16:12
  • Dann markiere doch noch bitte die Antworten, die dir geholfen haben;-).
    Montag, 4. März 2019 22:54
  • Hallo!

    Es war diese Antwort die mir weitergeholfen hat. Ich hoffe das jetzt richtig ist. Nocheinmal um Irrtümer auszuschließen Mit If  -> Else if. Wie ich schon erwähnt hatte. Unter Access lief diese Procedure unter VBA.

    mfg

    Peter

     

    Dienstag, 5. März 2019 16:00