sql >> Database >  >> RDS >> PostgreSQL

De bovenste functie van Postgres op een Turks teken geeft het verwachte resultaat niet terug

Uw probleem is 100% Windows. (Of liever Microsoft Visual Studio, waarmee PostgreSQL is gebouwd, om precies te zijn.)

Voor de goede orde, SQL UPPER uiteindelijk belt Windows' LCMapStringW (via towupper via str_toupper ) met bijna alle juiste parameters (locale 1055 Turks voor een UTF-8 -encoded, Turkish_Turkey database),

maar

de Visual Studio Runtime (towupper ) stelt de LCMAP_LINGUISTIC_CASING niet in bit in LCMapStringW 's dwMapFlags . (Ik kan bevestigen dat deze instelling werkt.) Dit wordt door Microsoft niet als een bug beschouwd; het is zo ontworpen en zal waarschijnlijk nooit "opgelost" worden (oh de geneugten van nalatenschap.)

Je hebt hier drie manieren voor:

  • implementeer de wrapper-oplossing van @Sorrow (of schrijf uw eigen native functievervanging (DLL).)
  • voer uw PostgreSQL-instantie uit op b.v. Ubuntu die het juiste gedrag vertoont voor Turkse locaties (@Sorrow bevestigde dat het voor hem werkt); dit is waarschijnlijk de eenvoudigste en schoonste uitweg.
  • plaats een gepatchte 32-bits MSVCR100.DLL in je PostgreSQL bin directory (maar hoewel UPPER en LOWER zou werken, kunnen andere dingen zoals het sorteren blijven mislukken - nogmaals, op Windows-niveau. YMMV.)

Voor de volledigheid (en nostalgisch plezier) ALLEEN , hier is de procedure om een ​​Windows-systeem te patchen (maar onthoud, tenzij u deze PostgreSQL-instantie van de wieg tot het graf beheert, kunt u uw opvolger(s) veel verdriet bezorgen); wanneer u een nieuw test- of back-upsysteem implementeert van kras jij of je opvolger(s) zouden eraan moeten denken om de patch opnieuw toe te passen -- en laten we zeggen dat je op een dag upgradet naar PostgreSQL 10, die zegt MSVCR120.DLL te gebruiken in plaats van MSVCR100.DLL , dan moet je ook je geluk beproeven met het patchen van de nieuwe DLL.) Op een testsysteem

  • gebruik HxD om C:\WINDOWS\SYSTEM32\MSVCR100.DLL te openen
  • Sla de DLL meteen op met dezelfde naam onder je PostgreSQL bin directory (probeer het bestand niet te kopiëren met Explorer of de opdrachtregel, ze kunnen de 64-bits versie kopiëren)
  • met het bestand nog steeds geopend in HxD, ga naar Zoeken> Vervangen , kies Datatype:Hexvalues , dan
    • zoeken naar...... 4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 00
    • vervangen door... 4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 01
    • ...dan nog een keer...
    • zoeken naar...... FC 51 6A 01 8D 4D 08 51 68 00 02 00 00 50 E8 E2
    • vervangen door... FC 51 6A 01 8D 4D 08 51 68 00 02 00 01 50 E8 E2
  • ...en opnieuw opslaan onder de PostgreSQL bin directory, start PostgreSQL opnieuw en voer uw query opnieuw uit.
    • als uw zoekopdracht nog steeds niet werkt (zorg ervoor dat uw database UTF-8-gecodeerd is met Turkish_Turkey voor beide LC_CTYPE en LC_COLLATE ) open postgres.exe in 32-bit Dependency Walker en zorg ervoor dat het aangeeft dat het MSVCR100.DLL . laadt uit de PostgreSQL bin directory.
    • als alle functies goed werken, kopieert u de gepatchte DLL naar de productie PostgreSQL bin map en start opnieuw.

MAAR ONTHOUD dat op het moment dat u de gegevens van het Ubuntu-systeem of van het gepatchte Windows-systeem naar een niet-gepatcht Windows-systeem verplaatst, u het probleem opnieuw zult hebben en dat u deze gegevens mogelijk niet meer kunt importeren in Ubuntu als de Windows-instantie duplicaten heeft geïntroduceerd in een citext veld of in een UPPER /LOWER -gebaseerde functie-index.



  1. Is er een manier om een ​​tekstkolom met regex-patronen nuttig te indexeren?

  2. Postgres is de coolste database – Reden #2:The License

  3. 2ndQuadrant Deutschland – Special Training Opening Koopje

  4. Postgres bulk insert/update die injectieveilig is. Misschien een functie waarvoor een array nodig is?