Oracle: Umlaute konvertieren

Hallo.

Ich muss für eine Wortliste die alphabetische Sortierung nach DIN einhalten. Oracle macht das aber von haus aus nicht. Umlaute werden nicht so eingeordnet wie sie sollen: Also Ä = AE und damit nach AD bzw. vor AF.
Ich habe ein wenig gesucht und bin auf diese Funktionsliste gestoßen:
http://www.techonthenet.com/oracle/functions/index_a… (wie macht man hier eigentlich „kurze Links“?)

Allerdings hab ich noch nicht allzuviel Erfahrung mit Oracle-Datenbanken und außerdem hab ich so auf den ersten Blick nichts gefunden, was mir sofort weiterhelfen würde. Die Funktion replace kommt meiner Problemstellung wohl am nächsten, aber vielleicht kann mir auch convert irgendwie weiterhelfen.

Jemand ne Idee, wie ich das schnell und schmerzlos umsetze? Wäre recht umständlich, wenn ich mit replace nach allen Umlauten suchen und hin und her konvertieren müsste.

Bernd

Hi Bernd,

also, der CONVERT wird Dir nicht viel weiterhelfen. Aber der REPLACE könnte das Problem lösen:

SELECT spaltemitdenumlauten
 FROM tabelle
 ORDER BY replace(replace(replace(replace(spalte,'ß','SS'),'Ü','UE'),'Ö','OE'),'Ä','AE')

Ein bisserl unübersichtlich mit den geschachtelten REPLACEs, aber ich habe das mit 9.2.0.4 ausprobiert, das funzt.

Viele Grüße
Bonsai

Mahlzeit,

Ich muss für eine Wortliste die alphabetische Sortierung nach
DIN einhalten. Oracle macht das aber von haus aus nicht.

Moment - genau dafür ist der Parameter NLS_SORT vorgesehen, bzw. die Funkrion NLSSORT:

http://download-west.oracle.com/docs/cd/B14117_01/se…

Für dein Beispiel müßte es reichen,
select * from Wortliste order by nlssort(Wort, ‚NLS_SORT=GERMAN‘);

einzugeben. Lies dir die Doku an dem angegebenen Link durch, besonders die Beispiele im hinteren Teil.

Gruß

Sancho

SELECT spaltemitdenumlauten
FROM tabelle
ORDER BY
replace(replace(replace(replace(spalte,‚ß‘,‚SS‘),‚Ü‘,‚UE‘),‚Ö‘,‚OE‘),‚Ä‘,‚AE‘)

Zu umständlich, ich müsste für die Anzeige ja wieder das Gegenteil machen. Inakzeptabel.

Bernd

Moment - genau dafür ist der Parameter NLS_SORT vorgesehen,
bzw. die Funkrion NLSSORT:
Für dein Beispiel müßte es reichen,
select * from Wortliste order by nlssort(Wort,
‚NLS_SORT=GERMAN‘);

Leider ist das auch nicht ganz das was ich suche, denn hier werden die Umlaute einfach „kastriert“. ä wird als a behandelt, ü als u usw. und dementsprechend eingeordnet. Das ist aber auch falsch. :frowning:

Ich hab noch vergessen zu erwähnen, dass die Abfrage sowohl mit dem LIKE als auch mit BETWEEN-Operator gehen muss.

Bernd

Hallo Bernd,

SELECT spaltemitdenumlauten
FROM tabelle
ORDER BY
replace(replace(replace(replace(spalte,‚ß‘,‚SS‘),‚Ü‘,‚UE‘),‚Ö‘,‚OE‘),‚Ä‘,‚AE‘)

Zu umständlich, ich müsste für die Anzeige ja wieder das
Gegenteil machen. Inakzeptabel.

Nein, das REPLACE hat nichts mit der Anzeige zu tun, nur mit der Sortierung. Allerdings muß man vermutlich noch Groß-/Kleinschreibung berücksichtigen.
Da erscheint die NLSSORT-Geschichte vielversprechender. Ist da wirklich nichts passendes dabei? Habe jetzt keine Zeit, mir alle Beispiele und Varianten anzusehen, vermute aber, Du hast es auch noch nicht gemacht :wink:.

Gruß, muzel

Hi Bernd,

also, verwende als NLS_SORT-Parameter anstatt GERMAN den Wert XGERMAN_DIN, der tut das, was Du brauchst.

Und das mit dem NLSSORT(spalte,‚NLS_SORT=…‘) funktioniert auch in der WHERE-Klausel. Allerdings, aufpassen: Du mußt NLSSORT auf beiden Seiten des Operators verwenden, bzw. bei BETWEEN eben auch links und rechts vom AND.

Gruß
Bonsai

1 Like

also, verwende als NLS_SORT-Parameter anstatt GERMAN den Wert
XGERMAN_DIN, der tut das, was Du brauchst.

Hey, das wars! :smiley:
Mit „alter session set NLS_SORT=XGERMAN_DIN“ muss man nicht so viel basteln, funktioniert aber nur eingeschränkt…

Und das mit dem NLSSORT(spalte,‚NLS_SORT=…‘) funktioniert
auch in der WHERE-Klausel. Allerdings, aufpassen: Du mußt
NLSSORT auf beiden Seiten des Operators verwenden, bzw. bei
BETWEEN eben auch links und rechts vom AND.

Also grundsätzlich funktioniert das mit der Sortierung schon, aber irgendwie bekomm ich es nicht hin, dass er mir das auch bei LIKE/BETWEEN macht. Hab da schon rumgefrickelt, aber sobald ich das nlssort in der Where-Bedingung einbaue, bekomme ich keine Datensätze mehr. :frowning:

Beispiel-Query würde so aussehen:

select feld1, feld2, feld3, (select count(\*) from tab2 where...) 
from table
where lower(feld1) between 'a' and 'b' (oder auch like 'a%')
order by feld1, feld2

Kann mir einer sagen, warum die DB das bei between/like nicht macht, aber sonst schon?

Bernd

Mit „alter session set NLS_SORT=XGERMAN_DIN“ muss man nicht so
viel basteln, funktioniert aber nur eingeschränkt…

Yep, spart Tipperei :wink:

Also grundsätzlich funktioniert das mit der Sortierung schon,
aber irgendwie bekomm ich es nicht hin, dass er mir das auch
bei LIKE/BETWEEN macht. Hab da schon rumgefrickelt, aber
sobald ich das nlssort in der Where-Bedingung einbaue, bekomme
ich keine Datensätze mehr. :frowning:

Hm, wie ich schon schrub (ein Wort fürs Deutschbrett…), Du mußt NLSSORT beiderseits vom Operator verwenden. Leider ist Deinem Beispiel nicht wirklich zu entnehmen, was Du da versucht hast.

Der LIKE darf so oder so kein Problem haben. LIKE ‚A%‘ ist eben mit ‚A‘ beginnend. Mit NLSSORT hier zu erreichen, dass er auch ein ‚Ä‘ erkennt, weil ja dann eben ‚AE‘, dürfte schiefgehen. Kuck Dir mal die Codes an, die Oracle mit dem NLSSORT… erzeugt.

Kannst Du Dein Beispiel nochmal ein bisserl aussagekräfitger formulieren, was da nicht funktioniert bzw. was Du erwartest bzw. was in anderen Fällen funktioniert und nun nicht mehr?

LG
Bonsai

Hm, wie ich schon schrub (ein Wort fürs Deutschbrett…), Du
mußt NLSSORT beiderseits vom Operator verwenden. Leider ist
Deinem Beispiel nicht wirklich zu entnehmen, was Du da
versucht hast.

Ok, es geht doch, man muss es nur richtig machen. :smile:

select 
 feld
from 
 tabelle
where
 nlssort(lower(feld),'NLS\_SORT=XGERMAN\_DIN') 
 between 
 nlssort('a','NLS\_SORT=XGERMAN\_DIN') 
 and 
 nlssort('d','NLS\_SORT=XGERMAN\_DIN') 
order by
 nlssort(feld,'NLS\_SORT=XGERMAN\_DIN');

Schade, dass es dafür keine Vereinfachung gibt. :frowning:

Bernd