Announcement

Collapse
No announcement yet.

Mehrfachen Funktionsaufruf verhindern

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mehrfachen Funktionsaufruf verhindern

    Hallo Zusammen,

    ich habe wieder eine Frage zu einer SQL Abfrage in einer gespeicherten Prozedur und hoffe, dass ihr mir noch mal behilflich sein könnt.

    Code:
    SELECT     WERT1, WERT2, WERT3, WERT4,
               dbo.xyz_FUNKTION1(WERT1, WERT2, WERT3, WERT4) AS PREIS
    
    FROM       TAB1
    
    WHERE     (WERT1 = @Param1) AND (WERT2 = @Param2) AND (WERT3 = @Param3) 
    
    ORDER BY WERT1
    Bei dieser Abfrage ist es so, dass auch hier wieder eine SQL Funktion im SELECT Statement aufgerufen wird. (siehe Frage zu SQL Abfrage)

    Leider wird diese Funktion viel zu oft unnötig aufgerufen, weil sich der entscheidene Wert z.B. WERT4 nicht oft ändert und somit sich also der Rückgabewert ebenso nicht oft ändert.

    Ich habe mir sowas in der Art vorgestellt:

    Rufe die Funktion nur dann auf, wenn sich der Wert z.B. hier also z.B. WERT4 geändert hat, ansosnten nehme den zwischengespeicherten Rückgabewert der Funktion.

    Also eine Lösung mit CASE z.B.:

    Code:
    SELECT     WERT1, WERT2, WERT3, 
               
    	   CASE WERT4 WHEN @LastValueEqual_WERT4 THEN @StoredValueFromFunction ELSE dbo.xyz_FUNKTION1(WERT1, WERT2, WERT3, WERT4) AS 'PREIS' END
    
    FROM       TAB1
    
    WHERE     (WERT1 = @Param1) AND (WERT2 = @Param2) AND (WERT3 = @Param3) 
    
    ORDER BY WERT1

    Ist solch eine Auswertung innerhalb eines SELECTs möglich und für den Fall, wie würde man dies sinnvoll gestalten?

    Ich wäre für Tipps und Vorschläge sehr dankbar.

    Viele Grüße
    Pierre
    Zuletzt editiert von Falk Prüfer; 19.02.2010, 13:54. Reason: Threads getrennt und Verweis eingefügt

  • #2
    Hallo Pierre,

    also zuerst hab ich mit deiner Frage einen neuen Thread aufgemacht, da der andere ja offensichtlich erledigt war und dies einen neue Frage ist. (Einen Verweis zum anderen Thread habe ich eingefügt)

    Aber nun zu deiner Frage:
    Da SQL mengenorientiert und nicht datensatzorientiert arbeitet, gibt es keinen Bezug auf den "Vorgänger". Oder anders: es gibt schlicht und ergreifend keinen Vorgänger, da die Menge erst durch ein etwaiges ORDER BY eine Reihenfolge erhält. Bei der Sortierung ist jedoch das Select und einschränkende Where-, bzw. Join-Klauseln schon gelaufen.
    Hier solltest du also einfach auf den Caching-Mechanismus des Servers vertrauen, der sehr zuverlässig unnötige Lesevorgänge verhindert.

    Gruß Falk
    Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

    Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

    Comment


    • #3
      Mir würde speziell dazu einfallen das Ergebnis dieser Funktion in einer separaten Spalte abzulegen und einen UPDATE/INSERT Trigger zu definieren, der bei jedem UPDATE/INSERT den jeweiligen Wert neu berechnet. Dann wird der Wert nicht bei jeder Abfrage berechnet, sondern nur wenn der Wert in der DB geupdatet wird.
      Ausserdem ist der Aufruf der Funktion dann auch unabhängig vom Client-Programm.

      Natürlich ist die Information dann redundant. Aber in so einem Fall ist das durchaus akzeptabel.

      Comment


      • #4
        Danke für eure Hinweise.

        Ich habe jetzt die Clientanwendung so abgeändert, dass die Anwendung diese Unterscheidung abfängt und somit diese Aufgabe dem SQL Server entnommen.

        Viele Grüße
        Pierre

        Comment


        • #5
          Originally posted by PierreChanab View Post
          ... SQL Server ...
          Mach doch mal aus Deiner scalaren Funktion eine Tabellenwert Funktion
          und binde die mit "CROSS APPLY" ein
          Vielleicht hat Mr Sabin ja recht mit TSQL-Scalar-functions-are-evil

          Comment

          Working...
          X