Announcement

Collapse
No announcement yet.

Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

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

  • Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

    Hallo zusammen,

    ich möchte bei Euch etwas spezifisches fragen.

    Der Ausgangspunkt:
    Eine Java-Anwendung sendet eine SQL-Abfrage an Datenbank und kann abhängig von WHERE-Bedingungen die Ergebnissmenge über 600000 Datensätze liefern. Jeder Datensatz besteht dann aus ca. 30 Felder.
    Die Ergebnissmenge ist sehr groß und für den Benutzer (in unserem Fall) nicht notwendig.

    Die Idee:
    Meine Idee ist: Mit der auszuführenden Abfrage als Pre-Statement ein Statement bzw. einen Procedure/Function-Aufruf, welches/welcher die maximal zu ermittelnde Ergebnissmenge einschränkt. Bei der Überschreitung des Limits wäre die Auslösung der Exception wünschenswert (sie würde dann programmtechnisch abgefangen).

    SQL-Beispiel (Pseudocode):
    SET RESULT_LIMIT_FOR_SQL_DB_RESULT 100000;
    SELECT * FROM TABLE_WITH_1000000_DATAROWS WHERE ID IN (1...500000);


    Die Frage:
    Kennt jemand so ein Kommando bzw. Storage Procedure von MS SQL Server?

    Ich will diese Beschränkung und deren Auswertung SQL-serverseitig haben. Ich möchte nicht die 600000 Datensätze über die Leitung transportieren, um dann festzustellen, dass es eben zu viel ist und den Benutzer darüber zu benachrichtigen.

    Der Einsatz von TOP 100000 ist hier nicht zieleführend: Es wird immer abgeschnitten und Benutzer wird sich wundern, warum er sein gesuchtes Elemen nicht findet bzw. einige Benutzer dürfen entsprechend der Berechntigung die Suchen uneingeschränkt ausführen.

    Wenn jemand etwas Änliches gesehen/gelesen/implementiert hat, bitte ich um Unterstützung.

    Danke im Voraus.

    Valerij

  • #2
    So etwas könnte man in zwei Schritte teilen:
    - zuerst ein "select count(*) from tabelle where .... " ohne Felder und Sortkriterien, damit hat man die Anzahl
    - und dann entweder eine Userinfo, falls der Wert zu groß ist oder volles Lesen der Daten wie gehabt

    Problematisch ist es, wenn man zB eine komplexe where-Klausel hat, die vielleicht schon mal ein paar Minuten arbeitet, bevor das Ergebnis da ist. In diesem Fall müsste man das komplette Statement per stored proc ausführen und das Ergebnis in einer temporären Tabelle in der stored proc speichern. Da schaut man dann nach, wieviele Records es sind und je nach Vorgabe wird entweder das Resultset oder ein Fehlercode geliefert.

    bye,
    Helmut

    Comment


    • #3
      Hallo Helmut,

      vielen Dank für deine Antwort.

      Das, was du vorschlägst, war meine erste Idee. Und wie du schon auch angemerkt hast, es ist dann ineffizient, wenn ein Statement ausgeführt wird, welcher ca. 50 unterschiedlichen Joins hat und Unmenge von Spalten zusammenstellt.

      Mit Storage Procedure ist es im Prinzip gute Idee, aber ist wieder super ineffizient.
      In dem Fall, wenn die Menge größer als das Limit, ist es noch Ok. Es erfolgt die Benachrichtigung des Users.
      Wenn aber das Limit nicht erreicht ist, dann wird das Statement nochmals ausgeführt, um die Ergebnisse zu ermitteln.


      Ich erwarte eher eine SQL-Server-Funktion, welche während der Ausführung des SQL-Statements merkt, dass die Ergebnisse über die eingestellte Limit-Grenze gehen, und bricht die Abfrage mit einer entsprechenden Exception ab.

      Comment


      • #4
        ... und Unmenge von Spalten zusammenstellt.
        Also das mit der Spaltenanzahl lässt sich ja wohl schon klären, bevor man das select ausführt.
        Und wegen des Limits könnte man ja zB. ein select top 1234 .... verwenden und wenn der Client dann genau diese Anzahl an Records als Ergebnis erhält, dann kann er davon ausgehen, dass es mehr als dies 1234 gibt und eine entsprechende Meldung generieren. Hat das Ergebnis weniger Records als der Grenzwert, dann ist es okay.
        Ist hingegen die Zeit ein Faktor, könnte man das select in einem Thread ausführen, der nach Erreichen der Zeitgrenze gecancelt wird. Inwieweit dann der Server das merkt und darauf ebenfalls die Abfrage stoppt kann ich dir aber nicht sagen.

        bye,
        Helmut

        Comment


        • #5
          hallo,
          dank folgendem Beitrag weiss ich dass man SQL ausführen und Datensätze zählen in einem Statement machen kann. http://entwickler-forum.de/showthread.php?t=63383

          Code:
          SELECT   COUNT (*) OVER ()      ,  o.*FROM sys.objects AS o
          Allerdings verstehe ich den beschriebenen Sinn nicht. Stellen wir uns vor unser Limit ist bei 20.000 Datensätzen und wir suchen ein Auto mit der Eigenschaft Diesel bei einem Fahrzeugportal, welchen Sinn macht es dem Benutzer bei überschreiten von 20.000 Datensätzen gar keinen mehr anzuzeigen?

          Was macht dein Benutzer mit der Abfrage wenn er sie nicht bearbeitet? Warum verheißt er Ressourcen deines SQL-Servers wenn er die Ergebnisse nicht benötigt?

          Comment


          • #6
            Die Aufgabe ist hier nicht die Anzahl im gleichen Statement zu ermitteln sondern sowas wie "gar nicht ausführen oder so bald wie möglich abbrechen, wenn Ergebnis zu groß wird". Nachdem der SQL-Server nicht hellsehen kann, muss er wohl das Ergebnis ermitteln, um die Anzahl zu wissen. Das Riesenergebnis dann aber über eine ev. langsame Leitung zum Client zu schicken und dort wegen eines noch langsameren Datengrids wer weiß wie lange auf die Anzeige zu warten (mit der einzigen Option, das Programm ganz zu killen) ist sicher ein Punkt, der einen solche Fragen stellen lässt.
            Ich denke, die einzige Möglichkeit ist hier wirklich, die Abfrage an eine stored proc zu schicken und einen Grenzwert mitzugeben. Ist dieser zB. 2000, dann verwendet die stored proc ein TOP 2001 und schreibt das Ergebnis in eine temporäre Hilfstabelle. Ist die Recordanzahl in der Hilfstabelle 2000 oder weniger, wird das Ergebnis mittels select * from Hilfstabelle an den Client gesendet, ansonsten ein entsprechender Returncode gesendet.

            bye,
            Helmut

            Comment

            Working...
            X