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

sql_kww

Neuer Benutzer
Beiträge
3
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
 
Werbung:
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

Eine serverseitige Lösung fällt mir nicht ein, aber warum erzeugst Du vor der eigentlichen "grossen" SQL-Abfrage nicht einen einfachen COUNT(*) mit den selben JOIN und WHERE Bedingungen?


1. Abfrage
Code:
SELECT COUNT(*) FROM (..komplexe Abfrage..)

Wenn die Ergebnismenge von COUNT(*) > als X ist, dann kann ein gezielter TOP y eingesetzt werden.

2.
Code:
SELECT TOP y , col1, col2, ... FROM (..komplexe Abfrage..)


Da die Datenbank bei der 1. Abfrage ähnliche Dinge tut wie bei der 2., ist die Performance auch nicht ganz schlecht.

Grüße
Thomas
 
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

Hallo sql_kww,

Serverseitig ist das kein Problem nur ein bischen Arbeit:

Ich würde zuerst einmal eine Tabelle mit Benutzer oder Gruppe + RESULT_LIMIT_FOR_SQL_DB_RESULT erstellen
damit man die Werte für die einzelnen Benutzer oder Gruppen festhalten kann.

Dann hätte man auch schon eine Möglichkeit sich jederzeit die gesetzten Limits anzeigen zu lassen.
Code:
CREATE TABLE RESULT_LIMIT (USERNAME nvarchar(50), RESULT_LIMIT_FOR_SQL_DB_RESULT int)
Dann braucht man eine Funktion zum setzen der Zeilenzahl. Nennen wir sie mal sp_set_result_limit
Aufruf währe dann so oder so ähnlich:
Code:
EXEC sp_set_result_limit 'Benutzer', 100000
Dann noch die Funktion zum erzeugen einer Ergebnismenge

Aufruf währe dann so:
Code:
select * from sp_get_result(Benutzer)
Hier könnte man dann auch noch eine WHERE-Klausel mit übergeben

Die greift dann auf die Tabelle zu und holt sich die RESULT_LIMIT_FOR_SQL_DB_RESULT für den
jeweiligen Benutzer und gibt die Entsprechende Zeilenzahl zurück.

Habe ich das alles richtig verstanden.

Wenn Ja. Bei welchem Teil brauchst du Hilfe.

Gruß Charly
 
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

Hallo nochmal,

Eceptions

Wenn die eine Exeption haben willst kann man das auch noch in die Prozedur mit reinbauen
 
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

sorry, auf Antworten gedrückt.

Ist heute nicht mein Tag.

Eine Exeption bei überschreiten der maximalen Zeilenzahl kann man natürlich auch noch auslösen lassen. Soll die Funktion die Zeilen dann trozdem zurückgeben oder nur einen Fehlercode?

Gruß Charly
 
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

Hallo Thomas und Charly,

vielen Dank für eure Antworten.

Das, was ihr vorschlagt, habe ich auch als Erstes überlegt. Aber 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.

In beiden Vorschlägen von euch, wird die Abfrage doppelt ausgeführt.


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.


@Thomas: Die Abfragen werden von Hibernate automatisch anhand der zusammengelegten Objekte generiert. Deshalb so komplex. Wenn du meinst, dass die Objektstrukturen vielleicht unnötig komplex sind, dann hast du recht. Aber es ist jetzt ünmöglich in einem 10-jährigen und schon abgeschlossenen Projekt wegen der SQL-Optimierung das Ganzes umbauen, um die einfachere Objektenstruktur zu erzielen.
 
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

Hallo sql_kww,

zählen muss man schon.

Aber mann muss die Ergebnismenge nicht ausgeben oder die Stored Procedure bei eine Überschreitung der Ergenismenge weiter SQL-Abfragen ausführen lassen.

Dann könnte man das so lösen:

1. Programm ruft die SP auf.
2. SP führt die Abfrage aus. Wenn man die Zeilen-Einschränkung mit übergibt, erübrigt sich auch die Abfrage einer LIMIT-Tabelle. Einmal Abfragen muss man aber, sonst gibts keine Zeilenzahl.
2a. Mit @@ROWCOUNT Ergebnismenge prüfen und dann entscheiden
3a. Exception bei Überschreitung
3b. Rückgabe der Ergebnismenge

Jetzt wird die Abfrage nur noch einmal ausgeführt, es gibt keine Abfrage einer LIMIT-Tabelle, und bei Überschreitung des Limits wird eine Exception ausgelöst ohne weitere Abfragen auszuführen.

Hört sich doch gut an oder?

Gruß Charly
 
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

Hallo Charly,

es hört sich tatsächlich gut an. Danke.

Es wird aber gewünscht, dass die Abfrage schon zu dem Zeitpunkt gestoppt wird, wenn Ergebnismenge z.B. 100001 ist.

Laut deinem Vorschlag müssen z.B. die 600000 Datensätze komplett geholt, um dann festzustellen, dass soviel Datensätze gar nicht transportiert werden dürfen.

Danke für deine Mühe und Geduld ;)

Und noch etwas. Ich habe wegen Verwendung der SP noch nachgefragt: Dabei muss Hibernate-Logik ein Bißchen angepasst werden, was natürlich nicht so gut ist.
 
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

Hallo sql_kww,

die einzige Möglichkeit die mir jetzt noch einfällt ist es einen Cursor zu nehmen.

Dann hätten wir zwar die richtige Logik aber die falsche Geschwindigkeit.

Mit einem Cursor könntest du nämlich die Daten so lange durchlaufen bis du das Limit überschreitest und dann eine Exception zurückgeben.

Leider sind Cursor bei solchen Datenmengen keine Alternative.

Vielleicht fällt ja noch jemand anderem eine Lösung ein.

Gruß Charly
 
Werbung:
AW: Einschränkung der Ergebnissmengen mittels SQL-Befehls/System-Procedure

Hi,

Wieviele WHERE Bedingungen gibt's denn?
Vielleicht kann der JAVA Code ja schon Beschränkungen für die Auswahl der Bedingungen herstellen? :confused:
Lass den User einfach nicht wahllos auf "Ich will alles!" klicken, sondern leg gleich Kombinationen von Einschränkungen fest.
 
Zurück
Oben