sql >> Database teknologi >  >> RDS >> PostgreSQL

Postgres øvre funktion på tyrkisk karakter returnerer ikke forventet resultat

Dit problem er 100 % Windows. (Eller rettere Microsoft Visual Studio, som PostgreSQL blev bygget med, for at være mere præcis.)

For ordens skyld, SQL UPPER ender med at kalde Windows' LCMapStringW (via towupper via str_toupper ) med næsten alle de rigtige parametre (locale 1055 tyrkisk for en UTF-8 -kodet, Turkish_Turkey database),

men

Visual Studio Runtime (towupper ) indstiller ikke LCMAP_LINGUISTIC_CASING bit i LCMapStringW s dwMapFlags . (Jeg kan bekræfte, at indstillingen gør det.) Dette betragtes ikke som en fejl hos Microsoft; det er ved design, og vil sandsynligvis aldrig blive "fikset" (åh glæden ved arv.)

Du har tre veje ud af dette:

  • implementer @Sorrow's wrapper-løsning (eller skriv din egen indbyggede funktionserstatning (DLL).)
  • kør din PostgreSQL-instans på f.eks. Ubuntu som udviser den rigtige adfærd for tyrkiske lokaliteter (@Sorrow bekræftede, at det virker for ham); dette er nok den enkleste og reneste udvej.
  • indsæt en patchet 32-bit MSVCR100.DLL i din PostgreSQL bin mappe (men selvom UPPER og LOWER ville fungere, kan andre ting såsom sortering fortsætte med at mislykkes -- igen på Windows-niveau. YMMV.)

For fuldstændighedens skyld (og nostalgisk sjov) KUN , her er proceduren til at lappe et Windows-system (men husk, medmindre du skal administrere denne PostgreSQL-instans fra vugge til grav, kan du forårsage en masse sorg for din(e) efterfølger(e); hver gang du implementerer et nyt test- eller backupsystem fra scratch du eller dine efterfølgere skulle huske at anvende patchen igen -- og hvis lad os sige, at du en dag opgraderer til PostgreSQL 10, som siger bruger MSVCR120.DLL i stedet for MSVCR100.DLL , så skal du også prøve lykken med at patche den nye DLL.) På et testsystem

  • brug HxD for at åbne C:\WINDOWS\SYSTEM32\MSVCR100.DLL
  • gem DLL'en med det samme med det samme navn under din PostgreSQL bin bibliotek (forsøg ikke at kopiere filen ved hjælp af Stifinder eller kommandolinjen, de kan kopiere 64bit-versionen)
  • med filen stadig åben i HxD, gå til Søg> Erstat , vælg Datatype:Hexværdier , derefter
    • søg efter...... 4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 00
    • erstat med... 4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 01
    • ...så en gang til...
    • søg efter...... FC 51 6A 01 8D 4D 08 51 68 00 02 00 00 50 E8 E2
    • erstat med... FC 51 6A 01 8D 4D 08 51 68 00 02 00 01 50 E8 E2
  • ...og gem igen under PostgreSQL bin bibliotek, genstart derefter PostgreSQL og kør din forespørgsel igen.
    • hvis din forespørgsel stadig ikke virker (sørg for, at din database er UTF-8-kodet med Turkish_Turkey for begge LC_CTYPE og LC_COLLATE ) åbn postgres.exe i 32-bit Dependency Walker og sørg for, at den angiver, at den indlæser MSVCR100.DLL fra PostgreSQL bin bibliotek.
    • hvis alle funktioner godt kopierer den patchede DLL til produktions PostgreSQL bin bibliotek og genstart.

MEN HUSK, at i det øjeblik du flytter dataene fra Ubuntu-systemet eller fra det lappede Windows-system til et ikke-patchet Windows-system, vil du have problemet igen, og du kan muligvis ikke importere disse data tilbage til Ubuntu, hvis Windows-forekomsten introducerede dubletter i en citext felt eller i en UPPER /LOWER -baseret funktionsindeks.



  1. Underforespørgsel med ugyldig identifikationsfejl i sql

  2. Postgresql - Brug af underforespørgsler med alter-sekvensudtryk

  3. Postgres lokalitetsfejl

  4. JDBC-driver til Oracle 10G XE