-
Baldur,
Danke für die Anmerkung. Doch warum soll ich eine oberschlau Schlagmichtotsuperlösung erarbeiten, wenn es einfacher auch geht. Da muss ich niemanden mehr etwas beweisen.
kf
-
Weil eine Schlagmichtotsuperlösung vielleicht einfach nur geil ist;-)?
Aber im Ernst, deshalb mache ich ja die pragmatische Lösung, die Schlagmichtotsuperlösung ist im Clientumfeld eher die Regel, da SQL's und Ergebnisse sowieso grundsätzlich dynamisch sind.
Frag mal die Javafraktion auf der IBM i, die kennt solche Probleme gar nicht.
-
... irgendwie verstehe ich die Anforderung und eure Diskussion nicht. Unvollständige Selektionen gehen auch mit simplem statischem SQL mit Parametermarkern mit between oder auch mit like.
- Feld between lowval and highval => keine Einschränkung
- Feld between :wert and :wert => nur mit Feld = Wert
etwas aufgebohrt kann das auch größer, bzw kleiner
- Feld like '%' => keine Einschränkung
- Feld like :wert => nur mit Feld = Wert
etwas aufgebohrt kann das auch echtes like (alle Kunden, bei denen der Ort mit 'F' und der Name mit 'M' anfängt etc.).
Das brummt dann auch mit elementarem Index-Design.
D*B
-
Der obere SQL ist doch statisch mit Hostvariablen. Parametermarker gibts nur bei dynamischem SQL, was u.U. in ILERPG halt schwierig ist.
-
... schneller geschrieben als gedacht. Parametermarker braucht man da keine, man besetzt die Hostvariablen der nicht benötigten Selektionen mit loval/highval und die anderen jeweils mit dem Auswahlwert (like entsprechend).
D*B
-
Ja das geht auch, ist allerdings performancenegativ.
Wenn ich alle Paramter mit Low/High und nur 1 auf einen bestimmten Wert kann SQL nicht über Index optimieren. Wenn ich einen Parameter mit Leer prüfe und nur den gewünschten Parameter fülle, kann SQL den passenden Index nehmen.
-
 Zitat von Fuerchau
Ja das geht auch, ist allerdings performancenegativ.
Wenn ich alle Paramter mit Low/High und nur 1 auf einen bestimmten Wert kann SQL nicht über Index optimieren. Wenn ich einen Parameter mit Leer prüfe und nur den gewünschten Parameter fülle, kann SQL den passenden Index nehmen.
Und warum denn nicht?
Solange die Original-Spalte auf der linken Seite des Vergleichsoperators (BETWEEN) nicht verändert wird (z.B. durch eine Scalare Funktion) KANN der Optimizer einen regulären Binary Radix Tree Index verwenden.
Ob er es denn tut, hängt mit anderen Faktoren zusammen.
... und selbst wenn auf der linken Seite des Vergleichsoperators die Spalte verändert wird, kann der Optimizer sogar einen entsprechenden Derived Index verwenden.
Kleiner Tipp: bevor man irgendwelche Behauptungen in den Raum stellt, sollte man das Ganze doch mal ausprobieren.
-
 Zitat von B.Hauser
Und warum denn nicht?
Solange die Original-Spalte auf der linken Seite des Vergleichsoperators (BETWEEN) nicht verändert wird (z.B. durch eine Scalare Funktion) KANN der Optimizer einen regulären Binary Radix Tree Index verwenden.
Ob er es denn tut, hängt mit anderen Faktoren zusammen.
... und selbst wenn auf der linken Seite des Vergleichsoperators die Spalte verändert wird, kann der Optimizer sogar einen entsprechenden Derived Index verwenden.
Kleiner Tipp: bevor man irgendwelche Behauptungen in den Raum stellt, sollte man das Ganze doch mal ausprobieren.

... das Schnittmuster (Bild oben) interessiert mich wenig. Entscheidend ist, wie die Selektivität der einzelnen Bestandteile der where Klausel ist, wenn sich der Optimizer da verschätzt, dann geht das eh' in die Grütze. Mein Vorschlag ist gut lesbar (man sieht sofort, was gemeint ist) und praktisch erprobt, man sollte natürlich die Indexe mit den zu erwartenden where Klauseln aufeinander abstimmen, sprich: die mit der hohen Selektivität (z. B. Firma o.ä.9 nach vorne nehmen und diei Exoten (Telefonnummer o.ä) nach hinten.
D*B
-
Hallo,
nicht die schnellste aber bei uns so üblich wir bauen den ganzen String zusammen:
tmp.sql = 'select * from QSAUFPF where aqidaq > 0';
// Status
if statvon_sl <> *Blank ;
tmp.sql += ' and statAQ >= ' + '''' + statvon_sl + '''';
endif;
if statbis_sl <> *Blank ;
tmp.sql += ' and statAQ <= ' + '''' + statbis_sl + '''';
endif;
// Prüfstatus
if pergvon_sl <> *Blank ;
tmp.sql += ' and pergAQ >= ' + '''' + pergvon_sl + '''';
endif;
if pergbis_sl <> *Blank ;
tmp.sql += ' and pergAQ <= ' + '''' + pergbis_sl + '''';
endif;
...usw..
Dann prepare jnd Cursor.
je nach Dateigröße auch mal ohne weitere Indexe. Wobei bei uns immer das erste Feld der Primärindex ist. (Fortlaufende Nummer)
Programmierung
-
Wenn jeder seinen Senf dazugeben kann ... schlage ich noch eine Lösung mit statischem SQL vor (ebenfalls in hunderten Programmen eingesetzt)
Code:
Select ...
from ...
Where Column1 = Case When :Host1 > '' Then :Host1 Else Column1 End
and Column2 = Case When :Host2 <> 0 Then :Host1 Else Column2 End
and Column3 = Case When :Host3 < '2000-01-01' Then :Host3 Else Column3 End
... and so on
...
... und der Optimizer kann durchaus Indices verwenden (auch zusammengesetzte Indices) und je nach Auswahl sogar unterschiedliche Indices (und manchmal sogar mehrere Indices gleichzeitig - Index Merge!)
-
 Zitat von K_Tippi
Hallo,
nicht die schnellste aber bei uns so üblich wir bauen den ganzen String zusammen:
tmp.sql = 'select * from QSAUFPF where aqidaq > 0';
// Status
if statvon_sl <> *Blank ;
tmp.sql += ' and statAQ >= ' + '''' + statvon_sl + '''';
endif;
if statbis_sl <> *Blank ;
tmp.sql += ' and statAQ <= ' + '''' + statbis_sl + '''';
endif;
// Prüfstatus
if pergvon_sl <> *Blank ;
tmp.sql += ' and pergAQ >= ' + '''' + pergvon_sl + '''';
endif;
if pergbis_sl <> *Blank ;
tmp.sql += ' and pergAQ <= ' + '''' + pergbis_sl + '''';
endif;
...usw..
Dann prepare jnd Cursor.
je nach Dateigröße auch mal ohne weitere Indexe. Wobei bei uns immer das erste Feld der Primärindex ist. (Fortlaufende Nummer)
Hi,
also so etwas kann man machen. Würde ich aber nie posten. Solche SQL in Strings werden häufig nicht von den Change Management Systemen erkannt und sind bei großen DB Änderungen permanente Zeitbomben. Und dann gibt es noch Programmierer die den Sqlstate oder Sqlcode nicht abfragen und nach einiger Zeit fragt man sich warum die Daten auf den Systemen nicht mehr korrekt sind :-(
Bitte jetzt keine grosse Diskussion daraus machen.
Gruß
Michael
-
Da kann ich Dieter nur zustimmen.
Die Reihenfolge der Whereklausel ist bei Vergleichen ungleich "=" von entscheidender Bedeutung:
where F1 between :#V1 and :#V2
and F2 between :#V3 and :#V4
Wenn V1 = Minval und V2 = Maxval wird ein Tablescan erzwungen.
Und was das obige Zusammenstricken angeht so wird da nicht auf enthaltene Hochkommata innherhalb von Strings eingegangen.
In der Web-Community wird diesbezüglich auch auf SQL-Injection hingewiesen, wenn Eingabefelder vom Frontend kommen.
Du brauchst z.B. in StatVon-Variable nur eine Eingabe
=> ' or 1=1 or '
Und schon erhältst du alle Daten für die du u.U. nicht berechtigt bist.
Hostvariablen (Parametermarker) schützen vor SQL-Injection.
Similar Threads
-
By Tschabo in forum NEWSboard Programmierung
Antworten: 10
Letzter Beitrag: 11-03-21, 09:14
-
By msost in forum NEWSboard Programmierung
Antworten: 18
Letzter Beitrag: 07-04-17, 14:23
-
By chrisssiie in forum NEWSboard Programmierung
Antworten: 3
Letzter Beitrag: 05-09-16, 13:27
-
By labm in forum NEWSboard Programmierung
Antworten: 8
Letzter Beitrag: 07-05-15, 07:55
-
By mott in forum IBM i Hauptforum
Antworten: 7
Letzter Beitrag: 18-09-02, 15:42
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks