Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Spaß mit UPPERCASE / LOWERCASE ? (https://www.delphipraxis.net/205829-spass-mit-uppercase-lowercase.html)

rokli 21. Okt 2020 08:07

Spaß mit UPPERCASE / LOWERCASE ?
 
Moin,

Aufgabe: Einen Datensatz anhand eines Namens in einer DB finden.

Ein Editfeld enthält den zu suchenden Begriff: "König Günter".
Damit ich bei der Schreibweise kein Theater bekomme, habe ich die Vergleichswerte in Großschrift gewandelt:

Das Coding sieht so aus:
Delphi-Quellcode:
         
qryKd.SQL.Text    := sSQL +
         ' AND UPPER(Kd.Name1) LIKE ' + QuotedStr(UPPERCASE(TRIM(edtName1.Text)) + '%') +
         ' ORDER BY Kd.Name1';
und das kommt in der Query an:

Delphi-Quellcode:
   AND UPPER(Kd.Name1) LIKE 'KöNIG GüNTER%' ORDER BY Kd.Name1


Ich finde natürlich nicht einen Datensatz, da die Umlaute nicht in Großschrift übersetzt worden sind!

Nächste Idee: Alles auf Kleinschrift bringen:
Delphi-Quellcode:
         
qryKd.SQL.Text    := sSQL +
         ' AND LOWER(Kd.Name1) LIKE ' + QuotedStr(LOWERCASE(TRIM(edtName1.Text)) + '%') +
         ' ORDER BY Kd.Name1';
Ergebnis:
Delphi-Quellcode:
   AND LOWER(Kd.Name1) LIKE 'kÖnig günter%' ORDER BY Kd.Name1
Diesmal bleiben groß geschriebenen Umlaute auch in Großschrift.

Ich werde wohl die Umlaute durch die benötigten Ascii-Werte ersetzen müssen.

Weiß jemand, warum die Umlaute von UPPERCASE nicht groß gemacht werden, bzw. bei LOWERCASE nicht klein gemacht werden?

Klaus01 21. Okt 2020 08:10

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
.. schau mal hier -> https://www.delphipraxis.net/183060-...ute-nicht.html

Grüße
Klaus

Bernhard Geyer 21. Okt 2020 08:12

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Guckst du hier:
https://www.delphipraxis.net/183060-...ute-nicht.html

Hier würde ich aber empfehlen
1, Umstellen auf Parametrisierte Abfragen
2, Das uppercase auch für deinen Parameterwert auf DB-Ebene durchführen zu lassen
3, Überlegen das Feld Kd.Name1 auf DB-Ebene als Case-Insensitive anlegen zu lassen

dummzeuch 21. Okt 2020 08:17

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Zitat:

Zitat von rokli (Beitrag 1475855)
Weiß jemand, warum die Umlaute von UPPERCASE nicht groß gemacht werden, bzw. bei LOWERCASE nicht klein gemacht werden?

Es sind nicht nur Umlaute, mit denen man diesen Spaß haben kann, sondern auch andere Zeichen, z.B. Accents. Und da gibt es dann noch landesspezifische Unterschiede: In Frankreich oder Kanada werden Accents bei Großschreibung weggeleassen, im anderen Land nicht (ich weiß gerade nicht mehr, welches welches war).

Selbst wenn man die Konvertierung explizit selbst vornimmt ( if s[i]='ä' then s[i]:='Ä' ), ist noch immer nicht gesagt, dass dann die Datenbank-Engine gleich konvertiert. Es ist sicherer, beides von der Datenbank-Engine machen zulassen, sofern sie eine Konvertierungsfunktion zur Verfügung stellt.

Delphi-Quellcode:
qryKd.SQL.Text   := sSQL +
         ' AND UPPER(Kd.Name1) LIKE UPPER(' + QuotedStr(UPPERCASE(TRIM(edtName1.Text)) + '%') + ')' +
         ' ORDER BY Kd.Name1';

rokli 21. Okt 2020 08:21

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Spitze! - Ich hatte nicht damit gerechnet, das das schon dokumentiert war - sorry! Hätte ich nach suchen sollen!

Aber zum Thema: Mit ASCILOWER und ASCIUPPER läuft das!

Danke!!

rokli 21. Okt 2020 08:25

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Die Konvertierung beider Werte in der IBM DB2 erscheint mir hier noch die beste Lösung zu sein! Das läuft nun auch schon so.

Vielen Dank an Bernhard und dummzeuch!

(Schreibfehler korrigiert)

mkinzler 21. Okt 2020 09:09

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
DB2 scheint expression indices zu unterstützen. Das wäre dann der Weg der Wahl.

rokli 21. Okt 2020 09:19

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
da hab ich leider keinen Einfluss drauf - die DB wird von einem externen Softwareanbieter gepflegt.

Uwe Raabe 21. Okt 2020 09:41

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
So richtig spaßig wird es dann mit den beiden türkischen i's: How to uppercase Turkish “i”?

Zitat:

In Turkish, there are two i

Dotless: ı, I
Dotted: i, İ
PROBLEM: Every time I uppercase an i, I get an I.

I want to get an İ (only in Turkish) when I uppercase an i, and an I when I uppercase an ı.

rokli 21. Okt 2020 11:07

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Hallo Uwe,

jetzt sag nicht, dass Du auch noch türkisch sprichst??

jobo 21. Okt 2020 11:52

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
I Like! ;)

Ich würde empfehlen, immer auf beiden Seiten die DB Funktion zu nutzen, um eine "analoge" Funktion zu erhalten.
Ein UpperCase auf der Spalte macht allerdings einen Index unbrauchbar und verlangsamt die Suche deutlich.
Lösungen wären einerseits Expression Indizes wie schon gesagt, allerdings ist es meist nicht vertretbar, alle denkbaren Felder mit diesen Indizes zu versehen. Andererseits gibt es auch Lösungswege über erweiterte like Operatoren (ilike) und jenachdem auch spezielle Collations oder normalisierte Suchspalten.

Uwe Raabe 21. Okt 2020 13:15

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Zitat:

Zitat von rokli (Beitrag 1475874)
Hallo Uwe,

jetzt sag nicht, dass Du auch noch türkisch sprichst??

Nein, nicht wirklich. Aber ich hatte mal einen Kunden in Istanbul.

himitsu 21. Okt 2020 14:06

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Zu schön wäre es, wenn jemand Parameter benutzen würde,

aber nocc toller wäre es, wenn endlich mal niemand mehr das QuoteStr für SQL-Statements benutzen täte, denn dafür ist es nicht da und auch noch total falsch.

Delphi-Quellcode:
EdPfad.Text := 'E:\inPfad\';
SQL.Text := 'SELECT * FROM irgendwas WHERE sonstwas = ' + QuoteStr(EdPfad) + ' AND nochwas';
Es ist hier zwar schwerer ein DROP DATABASE ins Edit zu schreiben, aber zumindestens kann man ganz leicht das SQL verrecken lassen (Syntaxfehler, mit nur einem einzigen \)

Einer unserer Kunden kam auf die geile Idee ' in Artikelnamen zu benutzen,
was besonders toll Endete, als diese Strings von Delphi durch Python, zurück in PascalScript und zu PSQL wanderte.
Teilweise mehrfaches Escaping mit unterschiedlichen Syntaxen (Pascal/Pythen/SQL).

QuoteString kennt ausschließlich die Syntax von Pascal-Strings, also nur das '.

rokli 27. Okt 2020 09:21

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Hallo himitsu,

Zitat:

Zitat von himitsu (Beitrag 1475901)
aber nocc toller wäre es, wenn endlich mal niemand mehr das QuoteStr für SQL-Statements benutzen täte, denn dafür ist es nicht da und auch noch total falsch.

Ich wäre Dir sehr dankbar, wenn Du mir Deine Version - ohne QuotedStr - einmal zeigen würdest!
Vielen Dank für Deine Mühe!

Bernhard Geyer 27. Okt 2020 09:37

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Zitat:

Zitat von himitsu (Beitrag 1475901)
Einer unserer Kunden kam auf die geile Idee ' in Artikelnamen zu benutzen,
was besonders toll Endete, als diese Strings von Delphi durch Python, zurück in PascalScript und zu PSQL wanderte.
Teilweise mehrfaches Escaping mit unterschiedlichen Syntaxen (Pascal/Pythen/SQL).

Hatten mal eine CRM das auch mit (dem Access-Gegenstück zu) direkten Zusammenbau und Ausführen von Queries gearbeitet hat.
Ein DropDatabase wäre leicht möglich (hat keiner gemacht).
Aber die "bösen Franzosen" mit ihren ' in den Adressen ...

Delphi.Narium 27. Okt 2020 11:14

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Zitat:

Zitat von rokli (Beitrag 1476175)
Hallo himitsu,

Zitat:

Zitat von himitsu (Beitrag 1475901)
aber nocc toller wäre es, wenn endlich mal niemand mehr das QuoteStr für SQL-Statements benutzen täte, denn dafür ist es nicht da und auch noch total falsch.

Ich wäre Dir sehr dankbar, wenn Du mir Deine Version - ohne QuotedStr - einmal zeigen würdest!
Vielen Dank für Deine Mühe!

Delphi-Quellcode:
qryKD.Close;
qryKd.SQL.Text := sSQL + ' AND UPPER(Kd.Name1) LIKE UPPER(:KdName) ORDER BY Kd.Name1';
qryKD.Params[0].AsString := TRIM(edtName1.Text) + '%';
// oder über den Parameternamen:
qryKD.ParamByName('KdName').AsString := TRIM(edtName1.Text) + '%';
qryKD.Open;

rokli 27. Okt 2020 11:30

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Danke, Delphi.Narium

und was bedeutet:
Zitat:

Zitat von himitsu (Beitrag 1475901)
denn dafür ist es nicht da und auch noch total falsch.


Delphi.Narium 27. Okt 2020 12:20

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
QuotedStr setzt die Hochkommata pascalkonform und nicht sqlkonform.
Oft passt das mit den ' aber nicht immer und bei dem "nicht immer" ist es möglich, durch geschicktes setzen der Hochkommata "so mal eben" in ein gültig aussehendes SQL weitere SQL-Statements einzufügen, mit denen man im "Idealfall" den gesamten Datenbestand ruinieren kann.

Oder mal anders formuliert: Unter Zuhilfenahme von QuotedStr (bzw. dem Zusammenbau von SQLs durch das Zusammenfügen von Strings) kann man Schadcode in ein SQL einfügen und diesen dann per Open bzw. ExecSQL ausführen lassen.

Bei der Nutzung von Parametern ist dies nicht möglich. Egal was man da in den Parameter "reinschiebt", es wird immer als Gesamtes (als Inhalt) in einem einzigen Wert interpretiert.

Da QuotedStr nur das ' kennt, wird man mit QuotedStr bei allen Datenbanken, die auch noch was anderes als das ' unterstützen / verlangen, scheitern.

rokli 28. Okt 2020 07:44

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
Guten Morgen Delphi.Narium,

vielen Dank für Deine ausführlichen Informationen! Das war sehr hilf- und lehrreich für mich!

Da ich aber schon etliche hundert SQL Statements in dieser Form geschrieben habe, werde ich das in Zukunft so machen!

Beste Grüße

himitsu 28. Okt 2020 08:25

AW: Spaß mit UPPERCASE / LOWERCASE ?
 
QuoteStr:
Eine orgendliche SQL-Library sollte irgendwo eine Quote-/Escape-Funktion besitzen, welche die Sprache des entsprechenden SQL spricht.

Wenn man nicht umher kommt und den SQL-Text zusammensetzen muß,
entweder direkt oder mit Makros, dann sollte man eben auch die richtige Funktion benutzen.


In PgDAC z.B. gibt es eine/zwei Funktion mit zuvielen Parametern, welche 'Strings' und "Bezeicher" behandeln kann. (über Ableitung oder ClassHelper kann man sich dann die Verwendung vereinfachen und sie zum leichtern Auffinden auch direkt an die Klassen der Conneecton oder des Query anhängen)


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:00 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