none
Where mit Spalten-Zusammensetzung RRS feed

  • Frage

  • Hallo,

    Ich möchte eine Abfrage, die ich sonst in einer Programmiersprache zusammenstelle mit einer Transakt-Sql-Abfrage ausführen.

    Dabei habe ich das Problem, dass ich in der WHERE Klausel den/einen Spaltennamen dyn. zusammensetze:

    PNR = 3  // Port-Nummer

    WHEREString = " Select ... From ... Where Spalte" + PNR + "_AKTIV = 'J' "  es soll also die Spalte: Spalte3_Aktiv auf 'J' abgefragt werden.

    Mit Transakt-SQL funktioniert das nicht so:

    DECLARE @PNR as int SET @PNR = 3 SELECT ... FROM ... WHERE IM.PORT + @PNR + _AKTIV = 'J'

    Ein ähnliches Problem habe ich mit optionalen, nachfolgenden WHERE Komponenten:

    WHERE ...
    and case when @lVKZ = 1 then WR.WRVKZ is not NULL else 1=1 end  -- Nur MO mit akt. VKZ uebernehmen?
     and case when @lZU =  1 then VERL.ID is NULL else 1=1 end        -- Nur MO die noch keine! Zusage haben uebernehmen?
    

    Also wenn @lVK 1 ist, soll noch die Bedingung WR.WRVKZ is not NULL mit abgefragt werden usw.

    Wie löst man denn so etwas???

    Fred.

    Freitag, 29. November 2013 10:22

Antworten

  • Hallo Fred,

    für 1.)

    wenn Du dynamische Spalten (allgemeine Objektname) verwenden willst, musst Du zunächst die SQL Anweisung als Zeichenkette zusammenstellen, und dann via sp_executesql ausführen.

    Siehe dazu Erland Sommarskog: The Curse and Blessings of Dynamic SQL

    für 2.) formuliere die Bedingung um, denn sollte auch ohne CASE gehen, z. B.:

    WHERE ...
    	AND (@lVKZ <> 1 OR WR.WRVKZ IS NOT NULL)
    	AND (@lZU <> 1 OR VERL.ID IS NULL)
    Gruß Elmar

    • Als Antwort markiert perlfred Freitag, 29. November 2013 12:27
    Freitag, 29. November 2013 11:09
    Beantworter

Alle Antworten

  • Hallo Fred,

    für 1.)

    wenn Du dynamische Spalten (allgemeine Objektname) verwenden willst, musst Du zunächst die SQL Anweisung als Zeichenkette zusammenstellen, und dann via sp_executesql ausführen.

    Siehe dazu Erland Sommarskog: The Curse and Blessings of Dynamic SQL

    für 2.) formuliere die Bedingung um, denn sollte auch ohne CASE gehen, z. B.:

    WHERE ...
    	AND (@lVKZ <> 1 OR WR.WRVKZ IS NOT NULL)
    	AND (@lZU <> 1 OR VERL.ID IS NULL)
    Gruß Elmar

    • Als Antwort markiert perlfred Freitag, 29. November 2013 12:27
    Freitag, 29. November 2013 11:09
    Beantworter
  • Dafür wirst Du dynamisches SQL mit sp_executesql verwenden müssen.

    http://technet.microsoft.com/de-de/library/ms188001.aspx

    Da das aber auch so seine Nachteile hat, würde ich hier den Ansatz mal überdenken.
    Oft ist es auch machbar, eine Handvoll statische Abfragen zu schreiben anstelle einer dynamischen.


    Andreas Wolter | Microsoft Certified Master SQL Server

    Blog: www.insidesql.org/blogs/andreaswolter
    Web: www.andreas-wolter.com | www.SarpedonQualityLab.com

    Freitag, 29. November 2013 11:11
  • Hallo Elmar!

    zu 2.)

    So um die Ecke zu denken, darauf muss man erst einmal kommen!!

    Also wenn die boolsche Variable true ist -> die Bedingung soll wirksam werden, wird die erste Abfrage ausgeblendet (wird false) und nur die Bedingung des zweiten Teils wird durch die or Verknüpfung wirksam. Perfekt!!!!
    Umgedreht genauso, wenn die boolsche Variable false ist wird der erste Teil true und der zweite Teil nicht mehr wirksam.

    Danke! für diese universelle Lösung!!!!!

    zu1.)

    sp_executesql werde ich mir ansehen. An dieser Stelle hat aber Andreas vielleicht recht, ich werde mal prüfen, ob ich nicht mehere Abfragen verwenden kann.

    Freitag, 29. November 2013 12:27
  • Hallo Andreas!

    Danke für deinen Hinweis! Ich muss noch prüfen, ob das C# DataSet ein Problem mit der dyn. Abfrage hat, wenn ja werde ich deinen Hinweis umsetzen und mehere statische Abfragen in einem TabelAdapter definieren.

    Vielen Dank und ein schönes Wochenende.

    Fred.

    Freitag, 29. November 2013 12:35
  • Hallo Elmar!

    zu 2.)

    So um die Ecke zu denken, darauf muss man erst einmal kommen!!

    Also wenn die boolsche Variable true ist -> die Bedingung soll wirksam werden, wird die erste Abfrage ausgeblendet (wird false) und nur die Bedingung des zweiten Teils wird durch die or Verknüpfung wirksam. Perfekt!!!!
    Umgedreht genauso, wenn die boolsche Variable false ist wird der erste Teil true und der zweite Teil nicht mehr wirksam.

    Danke! für diese universelle Lösung!!!!!

    ...

    Das Problem bei dieser Form von Abfragen ist, das der Query Optimizer dafür eigentlich keinen Plan "optimieren" kann.

    Bei kleinen Datenmengen sicher vernachlässigbar.

    Kann einem später aber auf die Füße fallen. Hängt halt von ab...


    Andreas Wolter | Microsoft Certified Master SQL Server

    Blog: www.insidesql.org/blogs/andreaswolter
    Web: www.andreas-wolter.com | www.SarpedonQualityLab.com

    Freitag, 29. November 2013 12:40
  • Hallo Andreas!

    Danke für deinen Hinweis! Ich muss noch prüfen, ob das C# DataSet ein Problem mit der dyn. Abfrage hat, wenn ja werde ich deinen Hinweis umsetzen und mehere statische Abfragen in einem TabelAdapter definieren.

    Vielen Dank und ein schönes Wochenende.

    Fred.

    Idealerweise steckt der Code in einer Prozedur. Was diese dann wiederum selber ausführt, sollte dem DataSet egal sein.

    Und sp_executesql ist selber ja auch nur eine Prozedur. :-)

    schönes Wochenende,

    Andreas


    Andreas Wolter | Microsoft Certified Master SQL Server

    Blog: www.insidesql.org/blogs/andreaswolter
    Web: www.andreas-wolter.com | www.SarpedonQualityLab.com

    Freitag, 29. November 2013 12:42
  • Hallo Andreas,

    nichts im Leben ist umsonst, wie man so schön sagt ;)

    Das war jetzt nur einfache boolsche Logik.

    Anhand der Fragmente will ich aber keine weiteren Ableitungen machen.

    Gruß Elmar

    Freitag, 29. November 2013 13:50
    Beantworter
  • Hallo Fred,

    solange das DataSet nicht typisiert ist, ist so ziemlich egal, was Du abfragst - nur Dein Programm muss damit zurechtkommen.

    Bei typisierten DataSets müssen Spaltennamen und Datentypen schon passen, sonst gibt es Probleme.

    Gruß Elmar

    Freitag, 29. November 2013 13:52
    Beantworter