Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQL Custom Sort (https://www.delphipraxis.net/155005-sql-custom-sort.html)

-187- 5. Okt 2010 07:48

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:
SortColumn:=DBGrid1.Columns.Items[Column.Index].FieldName;
SortOrder:='ASC';
IBQuery1.SQL.Text:='SELECT * FROM MYFIELED ORDER BY ' + SortColumn + ' ' + SortOrder;
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:

Code:
144
27
4
68
88
Heisst also das nur die erste Ziffer beim sortieren beachtet wird. Naütrlich hätte ich es gerne so:

Code:
4
27
68
88
144
Jetzt hab ich gelesen das man es mit CustomSort versuchen könnte aber ehrlich gesagt fehlt mir der Ansatz. Jemand eine Idee?

DeddyH 5. Okt 2010 08:04

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.

-187- 5. Okt 2010 08:32

AW: SQL Custom Sort
 
Zitat:

Evtl. kommt man mit einer View weiter, die versucht, den Wert nach Integer zu casten, aber dazu habe ich gerade kein Beispiel parat.
Versteh nur Bahnhof, kannste das nochmal genauer erklären vielleicht weiss ich dann wonach ich suchen kann :)

DeddyH 5. Okt 2010 08:38

AW: SQL Custom Sort
 
SQL-Code:
SELECT CAST(Feldname AS INTEGER) FROM Tabelle
So meinte ich das. Wenn allerdings nicht-numerische Werte vorhanden sind wird das wohl daneben gehen.

-187- 5. Okt 2010 08:45

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 :!:

Bernhard Geyer 5. Okt 2010 08:47

AW: SQL Custom Sort
 
Dann implementier dir doch eine eigene Sortierung auf Clientseite.

-187- 5. Okt 2010 08:49

AW: SQL Custom Sort
 
Sag das nicht so einfach daher :) Wäre nett wenn du ein Beispiel oder ein Tutorial dafür hättest.

nachti1505 5. Okt 2010 08:54

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;

-187- 5. Okt 2010 08:58

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 ^^

nachti1505 5. Okt 2010 09:56

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 ^^

schlecki 5. Okt 2010 11:42

AW: SQL Custom Sort
 
firebird bietet eine UDF an, die genau das leistet: LPAD. Diese musst du allerdings einmal in die DB einbinden:

Code:
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'
danach kannst du es so aufrufen:

Code:
  select lpad(feld, 10, ' ') from table
Quelle

-187- 5. Okt 2010 11:57

AW: SQL Custom Sort
 
Das hört sich schon gut an aber trotzdem nochmal eine Frage:

Code:
select lpad(feld, 10, ' ') from table
Bedeutet das dass die ersten 10 Stellen mit einem Leerzeichen aufgefüllt werden ?

Danke !

DeddyH 5. Okt 2010 12:44

AW: SQL Custom Sort
 
http://www.firebirdsql.org/refdocs/l...-udf-lpad.html
Zitat:

Description: Returns the input string left-padded with padchars until endlength is reached.

joachimd 5. Okt 2010 12:49

AW: SQL Custom Sort
 
Zitat:

Zitat von -187- (Beitrag 1053877)
Code:
select lpad(feld, 10, ' ') from table
Bedeutet das dass die ersten 10 Stellen mit einem Leerzeichen aufgefüllt werden ?

LPAD Doku bei IBExpert:
Zitat:

Left-pads a string with spaces or with a user-supplied string until a given length is reached.

DeddyH 5. Okt 2010 12:50

AW: SQL Custom Sort
 
Ätsch, schneller :tongue:

joachimd 5. Okt 2010 12:55

AW: SQL Custom Sort
 
Zitat:

Zitat von DeddyH (Beitrag 1053887)
Ätsch, schneller :tongue:

OT: und warum gabs dann keine rote Schachtel? :?:

DeddyH 5. Okt 2010 12:56

AW: SQL Custom Sort
 
Zitat:

Zitat von joachimd (Beitrag 1053892)
OT: und warum gabs dann keine rote Schachtel? :?:

OT: die ist öfter mal in Urlaub ;)

-187- 5. Okt 2010 13:33

AW: SQL Custom Sort
 
Okay das hab ich kapiert, super. Werds gleich ausprobieren.

-187- 5. Okt 2010 13:45

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:
IBQuery1.SQL.Text:='SELECT * FROM MYTABLE ORDER BY ' + SortColumn + ' ' + SortOrder;
Muss ich das dann so anwenden: ?
Code:
IBQuery1.SQL.Text:='SELECT LPAD(*, 50, " ") FROM MYTABLE ORDER BY ' + SortColumn + ' ' + SortOrder;

DeddyH 5. Okt 2010 13:51

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.

-187- 5. Okt 2010 13:57

AW: SQL Custom Sort
 
Das hab ich versucht aber scheinbar mach ich irgendwas grundlegend falsch.

Den Table habe ich so erstellt:

Code:
...
IBTable1.TableName:='LIST';
IBTable1.FieldDefs.Add('LITEMS', ftString, 10, false);
...
Wenn ich mit folgenden Code den Zugriff versuche krieg ich immer den Fehler das dass Feld nicht gefunden wurde:

Code:
IBQuery1.SQL.Text:='SELECT LITEMS FROM LIST ORDER BY ' + SortColumn + ' ' + SortOrder;

DeddyH 5. Okt 2010 14:06

AW: SQL Custom Sort
 
Ich arbeite nie mit IBTable, aber ist das Feld denn wirklich vorhanden? Bekommst Du es mit einem
SQL-Code:
SELECT * FROM LIST
gelistet?

schlecki 5. Okt 2010 14:24

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:
select field1, field2, lpad(field3, 50, ' ') as field3 from table
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:

Code:
select lpad(t.field3, 50, ' ') t.field3, t.* from table t
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.

-187- 5. Okt 2010 14:41

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!

-187- 5. Okt 2010 15:24

AW: SQL Custom Sort
 
Zitat:

Implementation limit exceeded. Block size exceeds implementation restriction
Hmm zuviele Statements, was nun ?

-187- 5. Okt 2010 17:31

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...

DeddyH 5. Okt 2010 18:19

AW: SQL Custom Sort
 
Es wäre sicherlich sinnvoll, uns das SQL mal zu zeigen.

-187- 5. Okt 2010 18:25

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

nachti1505 5. Okt 2010 19:06

AW: SQL Custom Sort
 
Delphi-Quellcode:
select field1, field2, field3 from table order by lpad(field3, 50, ' ')

schlecki 5. Okt 2010 20:10

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:
select
  cast(lpad(feld1, 50, ' ') as varchar(50)) Feld1,
  cast(lpad(feld2, 50, ' ') as varchar(50)) Feld2,
  ...
from
  Table
Dann funktioniert es auch mit mehreren Feldern.

-187- 5. Okt 2010 20:10

AW: SQL Custom Sort
 
Ah okay danke, hast du auch ne Idee zu meinem Leerzeichen im Grid Problem ?

Edit: Klappt prima mit Cast !! Danke!

schlecki 5. Okt 2010 23:40

AW: SQL Custom Sort
 
Zitat:

Zitat von -187- (Beitrag 1053982)
Ah okay danke, hast du auch ne Idee zu meinem Leerzeichen im Grid Problem ?

siehe #29

-187- 6. Okt 2010 00:17

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.

DeddyH 6. Okt 2010 08:32

AW: SQL Custom Sort
 
Zitat:

Zitat von -187- (Beitrag 1054014)
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 :?:

Wo wird denn LPAD im geposteten Code verwendet? Richtig, beim Sortieren (und nur dort). Das hätte Dir aber auffallen müssen, wenn Du es einfach mal ausprobiert hättest.

-187- 6. Okt 2010 08:54

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;

DeddyH 6. Okt 2010 09:25

AW: SQL Custom Sort
 
Wie sieht denn "Mein LPAD Sorting Code" aktuell aus?

-187- 6. Okt 2010 12:22

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;

DeddyH 6. Okt 2010 12:25

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.

-187- 6. Okt 2010 15:38

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:

-187- 10. Okt 2010 01:35

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:
...
21104419
21927854
24498699
27539399
1003333
1011231
1016007
...
Es müsste aber so sein:

Code:
...
27539399
24498699
21927854
21104419
1016007
1011231
1003333
...


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:07 Uhr.
Seite 1 von 2  1 2      

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