Datenbank: Firebird • Version: 2.0 • Zugriff über: IBTable
SQL Custom Sort
Moin, ich hab noch ein Fehler in meiner Datenbank Anwendung entdeckt! :)
Mit folgendem Code sortiere ich meine Datenmenge:
Code:
MyField ist ftString,50 und enthält entweder eine Fehler MSG oder einen Zahlenwert. Jetzt möcht ich die Zahlenwerte natürlich absteigend oder aufsteigend sortiert haben aber musste folgende sortierte Reihenfolge festellen:
SortColumn:=DBGrid1.Columns.Items[Column.Index].FieldName;
SortOrder:='ASC'; IBQuery1.SQL.Text:='SELECT * FROM MYFIELED ORDER BY ' + SortColumn + ' ' + SortOrder;
Code:
Heisst also das nur die erste Ziffer beim sortieren beachtet wird. Naütrlich hätte ich es gerne so:
144
27 4 68 88
Code:
Jetzt hab ich gelesen das man es mit CustomSort versuchen könnte aber ehrlich gesagt fehlt mir der Ansatz. Jemand eine Idee?
4
27 68 88 144 |
AW: SQL Custom Sort
Die Sortierung ist völlig korrekt, da es sich ja um alphanumerische Werte handelt. Ich finde das DB-Design etwas unglücklich. Evtl. kommt man mit einer View weiter, die versucht, den Wert nach Integer zu casten, aber dazu habe ich gerade kein Beispiel parat.
|
AW: SQL Custom Sort
Zitat:
|
AW: SQL Custom Sort
SQL-Code:
So meinte ich das. Wenn allerdings nicht-numerische Werte vorhanden sind wird das wohl daneben gehen.
SELECT CAST(Feldname AS INTEGER) FROM Tabelle
|
AW: SQL Custom Sort
Ja hab das eben auch in einem anderen Thread hier gefunden. Klappt solange kein String vorhanden ist. Bei meinem System hab ich aber Integer und String Werte :!:
|
AW: SQL Custom Sort
Dann implementier dir doch eine eigene Sortierung auf Clientseite.
|
AW: SQL Custom Sort
Sag das nicht so einfach daher :) Wäre nett wenn du ein Beispiel oder ein Tutorial dafür hättest.
|
AW: SQL Custom Sort
Wenn deine Schlüssel eine feste maximal Länge haben (sollten sie ja eigentlich) und diese Maximal-Länge nicht zu lang ist, würde es vielleicht lohnen das Feld mit Leerzeichen aufzufüllen.
Aus "4" würde dann "_________4" werden. Dann funktioniert auch das Sortieren wieder. Im besten Fall bietet dir dein DBMS eine solchige Funktion an, die du dann einfach als Sortierkritierium mit übergibst.
Delphi-Quellcode:
IBQuery1.SQL.Text:='SELECT * FROM MYFIELED ORDER BY FILL_LEFT(' + SortColumn + ') ' + SortOrder;
|
AW: SQL Custom Sort
Ist FILL_LEFT eine SQL Funktion oder hast du das jetzt nur so als Bsp. genannt? Jedenfalls kennt mein DBMS diese Funktion nicht. Ja ich könnte beim Schreiben der Werte Leerzeichen dranhängen dann müsste es ja funktionieren. Ich hatte schon an führende Nullen gedacht aber das sieht mehr dann zu unübersichtlich aus. Auf Leerzeichen bin ich nicht gekommen ^^
|
AW: SQL Custom Sort
FILL_LEFT war jetzt ein Beispiel.... glaube gerade auch nicht, dass es eine ReverseOP zum trim gibt, aber diese sollte sich als StoedProcedure noch schnell selber schreiben lassen. Fest in den Datenbestand würde ich die Leerzeichen auf keinen Fall integrieren ^^
|
AW: SQL Custom Sort
firebird bietet eine UDF an, die genau das leistet: LPAD. Diese musst du allerdings einmal in die DB einbinden:
Code:
danach kannst du es so aufrufen:
DECLARE EXTERNAL FUNCTION lpad
CSTRING(255) NULL, INTEGER, CSTRING(1) NULL RETURNS CSTRING(255) FREE_IT ENTRY_POINT 'IB_UDF_lpad' MODULE_NAME 'ib_udf'
Code:
Quelle
select lpad(feld, 10, ' ') from table
|
AW: SQL Custom Sort
Das hört sich schon gut an aber trotzdem nochmal eine Frage:
Code:
Bedeutet das dass die ersten 10 Stellen mit einem Leerzeichen aufgefüllt werden ?
select lpad(feld, 10, ' ') from table
Danke ! |
AW: SQL Custom Sort
http://www.firebirdsql.org/refdocs/l...-udf-lpad.html
Zitat:
|
AW: SQL Custom Sort
Zitat:
Zitat:
|
AW: SQL Custom Sort
Ätsch, schneller :tongue:
|
AW: SQL Custom Sort
Zitat:
|
AW: SQL Custom Sort
Zitat:
|
AW: SQL Custom Sort
Okay das hab ich kapiert, super. Werds gleich ausprobieren.
|
AW: SQL Custom Sort
Hmm so wirklich hab ich's wohl noch nicht begriffen. Also ich muss die Funktion deklarieren. Muss ich das einmal machen und dann merkt die DB sich das oder muss ich das jedesmal machen wenn ich die Funktion nutzen möchte.
Desweiteren sah meine Sort Query so aus:
Code:
Muss ich das dann so anwenden: ?
IBQuery1.SQL.Text:='SELECT * FROM MYTABLE ORDER BY ' + SortColumn + ' ' + SortOrder;
Code:
IBQuery1.SQL.Text:='SELECT LPAD(*, 50, " ") FROM MYTABLE ORDER BY ' + SortColumn + ' ' + SortOrder;
|
AW: SQL Custom Sort
Verabschiede Dich vom Stern und sprich die benötigten Felder einzeln an (das entsprechende dann halt mit lpad). Alternativ kannst Du Dir auch eine View erstellen, die das für Dich macht.
|
AW: SQL Custom Sort
Das hab ich versucht aber scheinbar mach ich irgendwas grundlegend falsch.
Den Table habe ich so erstellt:
Code:
Wenn ich mit folgenden Code den Zugriff versuche krieg ich immer den Fehler das dass Feld nicht gefunden wurde:
...
IBTable1.TableName:='LIST'; IBTable1.FieldDefs.Add('LITEMS', ftString, 10, false); ...
Code:
IBQuery1.SQL.Text:='SELECT LITEMS FROM LIST ORDER BY ' + SortColumn + ' ' + SortOrder;
|
AW: SQL Custom Sort
Ich arbeite nie mit IBTable, aber ist das Feld denn wirklich vorhanden? Bekommst Du es mit einem
SQL-Code:
gelistet?
SELECT * FROM LIST
|
AW: SQL Custom Sort
also, das mit dem declare musst du einmalig pro db machen (bis firebird 2.0; ab 2.1 ist das bereits im server implementiert).
In deiner IBTable geht das geht (zumindest ohne eine View). verwende statt der Table einfach eine Query. Dort kannst du das SQL selbst festlegen:
Code:
Wenn du wirklich viele Felder hast und die auch alle abgefragt werden müssen (nicht optimal, daher ist die obere Variante besser, weil hier nur die wirklich benötigten Daten übertragen werden), ginge auch das:
select field1, field2, lpad(field3, 50, ' ') as field3 from table
Code:
wobei hier dann das ursprüngliche Feld auch nochmal(!) mitgeliefert wird. Allerdings ist hier der Name etwas angepasst, etwa Field3_1 oder Field31 - hängt glaube ich von der Version / den Komponenten ab.
select lpad(t.field3, 50, ' ') t.field3, t.* from table t
|
AW: SQL Custom Sort
Also der Grund warum ich alle Felder abgefragt habe ist eigentlich nur weil ich bisher dachte das man das beim sortieren muss. Aber jetzt klingt es so als müsste ich nur das zu sortierende Feld abfragen. Würde auch Sinn machen^ :D
Btw habe nochmal nachgeschaut habe doch FB2.1 also brauch ich den declare code nicht. Edit: Nein ich muss wirklich alle Felder abrufen ... Edit2: Okay habs getestet, im Grunde funktioniert es so. Dankeschön! |
AW: SQL Custom Sort
Zitat:
|
AW: SQL Custom Sort
Sobald ich 2mal LPAD im SQL Command habe krieg ich den Fehler: Implementation limit exceeded. Block size exceeds implementation restriction
Ich habe 11 Felder. Muss ich jetzt vor dem Sortieren jedesmal abfragen welches Feld geklickt wurde und für jedes Feld einen Eignen SQL Command schreiben in welchen dann das geklickte Feld mit LPAD versehen wird :/ Irgendwie eine blöse Lösung... |
AW: SQL Custom Sort
Es wäre sicherlich sinnvoll, uns das SQL mal zu zeigen.
|
AW: SQL Custom Sort
Hab das Problem jetzt gelöst indem ich mir für die betroffenen Felder ein eigenen SQL Command gebaut habe. Leider bin ich mit LPAD Lösung ein wenig unglücklich weil die Übersicht im DBGrid mit left padded Leerzeichen sehr merkwürdig aussieht. Kann ich die Leerzeichen irgendwie wieder entfernen bevor ich die Datenmenge im DBGrid einfüge?
Zb im OnDrawCell die Leerzeichen nicht "mit malen" :D |
AW: SQL Custom Sort
Delphi-Quellcode:
select field1, field2, field3 from table order by lpad(field3, 50, ' ')
|
AW: SQL Custom Sort
in der doku (links siehe in vorhergehenden Posts ;) ) kann man nachlesen, das die Funktion LPAD ein varchar(32k) zurück liefert. Bei einem geht das gut, bei mehreren hast du ein Problem.
Als Lösung wird empfohlen, noch einen Cast drumzuwickeln:
Code:
Dann funktioniert es auch mit mehreren Feldern.
select
cast(lpad(feld1, 50, ' ') as varchar(50)) Feld1, cast(lpad(feld2, 50, ' ') as varchar(50)) Feld2, ... from Table |
AW: SQL Custom Sort
Ah okay danke, hast du auch ne Idee zu meinem Leerzeichen im Grid Problem ?
Edit: Klappt prima mit Cast !! Danke! |
AW: SQL Custom Sort
Zitat:
|
AW: SQL Custom Sort
Versteh ich nicht, mit dem Code füge ich doch ein LPAD ein? Ich möchte doch grade kein LPAD im Grid haben sondern nur beim Sortieren :?:
Und natürlich möcht ich nicht an der Sortierung ändern. Also nachdem ich Sortiert habe möchte ich die LPADs wieder entfernen und dann erst die Datenmenge dem Grid übergeben. |
AW: SQL Custom Sort
Zitat:
|
AW: SQL Custom Sort
Ja ist ja richtig aber wenn ich dann meinem DBGrid als Datenmenge das Query zuordne dann hab ich die Left Paddings da mit drinne.
Delphi-Quellcode:
IBQuery1.SQL.Text:=Mein LPAD Sorting Code;
IBQuery1.Open; DBGrid1.DataSource.DataSet:=IBQuery1; |
AW: SQL Custom Sort
Wie sieht denn "Mein LPAD Sorting Code" aktuell aus?
|
AW: SQL Custom Sort
Code:
SortColumn:=DBGrid1.Columns.Items[Column.Index].FieldName; SortOrder:='ASC'; IBQuery1.SQL.Text:= 'SELECT FIELD0, FIELD1, FIELD2, FIELD3, '+ 'cast(lpad(FIELD4, 50, '' '') as varchar(50)) FIELD4, '+ 'FIELD5, FIELD6, FIELD7 from MYTABLE ORDER BY ' + SortColumn + ' ' + SortOrder; IBQuery1.Open; |
AW: SQL Custom Sort
Kein Wunder, wenn Du das LPAD im SELECT hast. Im geposteten Code war das lediglich in der ORDER BY-Klausel, schau noch einmal genau nach.
|
AW: SQL Custom Sort
Jap da hab ich wohl mal wieder gepennt. Ich danke euch allen, das Thema wäre dann endlich erledigt!!
Dankeschön :thumb: |
AW: SQL Custom Sort
Okay jetzt ist mir aufgefallen das es doch noch nicht so ganz klappt :(
Die sortiere Reihenfolge sieht jetzt so aus:
Code:
Es müsste aber so sein:
...
21104419 21927854 24498699 27539399 1003333 1011231 1016007 ...
Code:
...
27539399 24498699 21927854 21104419 1016007 1011231 1003333 ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz