Sie sind nun wieder eingeladen, die Diskussion spezieller technischer Probleme mit zu verfolgen. Bitte schicken Sie Fragen, Anregungen oder Antworten zu den vorgestellten Themen – ebenso wie Ihre Kritik – an unsere e-Mail-Adressen: dieter.bender@MidrangeMagazin.de oder Redaktion@MidrangeMagazin.de Frage: Bei uns bricht ein Anzeigeprogramm ab, weil ein Textfeld nicht darstellbare Zeichen enthält. Wie kann man alle Sätze in einer Datei finden, die ein solches Problem verursachen könnten?
Antwort: Auf den ersten Blick scheint das nur per Programm möglich zu sein – und selbst das erfordert noch einen Augenblick des Nachdenkens.
Der Bereich von Hexadezimal 00 bis 3A ist im EBCDIC für Steuerzeichen reserviert, und in dieser Zeichenmenge liegen auch die Zeichen, die bei der Anzeige einer Bildschirmdatei in den Feldern nicht erwartet werden. Wenn es denn eine Chance gibt, diese Aufgabenstellung ohne Programm zu lösen, dann mit SQL. Der erste Ansatz, es mit einer LIKE-Abfrage zu versuchen, artet bei der Menge der abzufragenden Zeichen in fehlerträchtige Tipparbeit aus. Zur Ermittlung aller Sätze, bei denen ein bestimmtes Feld Umlaute enthält, sähe das mit der LIKE-Variante noch recht überschaubar aus.
select * from KUNDE where NACHNAME like '%ä%' or NACHNAME like '%ö%' or NACHNAME like '%ü%' or NACHNAME like '%Ä%' or NACHNAME like '%Ö%' or NACHNAME like '%Ü%' or NACHNAME like '%ß%'
Die Laufzeit von dieser Abfrage ist bei großen Datenmengen schon erheblich, lässt sich aber unter Verwendung der Funktion TRANSLATE verbessern.
select * from KUNDE where NACHNAME <> translate(NACHNAME, ' ', 'ÄÖÜäöüß')
Bei dieser Variante ersetzt die SQL-Funktion TRANSLATE alle Umlaute durch Blanks und der Vergleich mit dem Ursprungsfeld selektiert die Sätze, bei denen eine Umwandlung stattgefunden hat.
Mit diesem Ansatz lässt sich auch die Ausgangsfrage elegant lösen; man braucht lediglich einen TRANSLATE zu verwenden, der alle Zeichen kleiner als Hexadezimal 40 durch Blanks ersetzt und muss dann in der Where-Klausel wiederum diejenigen Sätze selektieren, bei denen eine Umwandlung stattgefunden hat.
select * from Datei where TEXTFELD <> translate(TEXTFELD, ' ', x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F')
Die Laufzeit dieser Abfrage ist durchaus noch erträglich; es wird zwar ein Full Table Scan erzwungen, aber es gibt keine rekursive Komponente – wie bei der Verwendung von LIKE mit einem %-Zeichen am Anfang des Vergleichswertes.
Wenn man Steuerzeichen in mehreren Feldern sucht, dann muss man die Felder entweder miteinander verketten oder kann mehrere Bedingungen mit „oder“ koppeln.
select * from Datei where Feld1 <> translate(Feld1, ' ', x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F') or Feld2 <> translate(Feld2, ' ', x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F')
Den Autor Dieter Bender erreichen Sie unter dieter.bender@midrangemagazin.de