Ihr Problem ist 100 % Windows. (Oder genauer gesagt Microsoft Visual Studio, mit dem PostgreSQL erstellt wurde.)
Für den Datensatz SQL UPPER ruft schließlich LCMapStringW von Windows auf
(über towupper
über str_toupper
) mit fast alle richtigen Parameter (Gebietsschema 1055 Türkisch für ein UTF-8 -kodiert, Turkish_Turkey Datenbank),
aber
die Visual Studio Runtime (towupper ) legt den LCMAP_LINGUISTIC_CASING nicht fest
Bit in LCMapStringW 's dwMapFlags . (Ich kann bestätigen, dass die Einstellung ausreicht.) Dies wird bei Microsoft nicht als Fehler betrachtet; es ist beabsichtigt und wird wahrscheinlich nie "behoben" (Oh, die Freuden des Vermächtnisses.)
Sie haben drei Auswege:
- Implementieren Sie die Wrapper-Lösung von @Sorrow (oder schreiben Sie Ihre eigene native Funktionsersetzung (DLL).)
- Führen Sie Ihre PostgreSQL-Instanz auf z. Ubuntu das das richtige Verhalten für türkische Gebietsschemata zeigt (@Sorrow bestätigte, dass es für ihn funktioniert); das ist wahrscheinlich der einfachste und sauberste Ausweg.
- fügen Sie eine gepatchte 32-Bit-
MSVCR100.DLLein in Ihrem PostgreSQL-binVerzeichnis (aber obwohlUPPERundLOWERfunktionieren würde, können andere Dinge wie die Sortierung weiterhin fehlschlagen – wiederum auf Windows-Ebene. YMMV.)
Der Vollständigkeit halber (und nostalgischer Spaß) NUR , hier ist das Verfahren zum Patchen eines Windows-Systems (aber denken Sie daran, wenn Sie diese PostgreSQL-Instanz nicht von der Wiege bis zur Bahre verwalten, können Sie Ihren Nachfolgern viel Kummer bereiten); wann immer Sie ein neues Test- oder Sicherungssystem von bereitstellen Sie oder Ihre Nachfolger müssten daran denken, den Patch erneut anzuwenden – und wenn wir sagen, dass Sie eines Tages ein Upgrade auf PostgreSQL 10 durchführen, das beispielsweise MSVCR120.DLL verwendet statt MSVCR100.DLL , dann müssen Sie auch Ihr Glück mit dem Patchen der neuen DLL versuchen.) Auf einem Testsystem
- benutze HxD
um
C:\WINDOWS\SYSTEM32\MSVCR100.DLLzu öffnen - Speichern Sie die DLL sofort unter dem gleichen Namen unter Ihrem PostgreSQL
binVerzeichnis (versuchen Sie nicht, die Datei mit dem Explorer oder der Befehlszeile zu kopieren, sie könnten die 64-Bit-Version kopieren) - während die Datei noch in HxD geöffnet ist, gehen Sie zu Suchen> Ersetzen , wählen Sie Datentyp:Hexwerte , dann
- Suche nach......
4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 00 - ersetzen durch...
4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 01 - ...dann noch einmal...
- Suche nach......
FC 51 6A 01 8D 4D 08 51 68 00 02 00 00 50 E8 E2 - ersetzen durch...
FC 51 6A 01 8D 4D 08 51 68 00 02 00 01 50 E8 E2
- Suche nach......
- ...und unter dem PostgreSQL-
binerneut speichern Verzeichnis, starten Sie dann PostgreSQL neu und führen Sie Ihre Abfrage erneut aus.- wenn Ihre Abfrage immer noch nicht funktioniert (stellen Sie sicher, dass Ihre Datenbank mit
Turkish_TurkeyUTF-8 codiert ist für beideLC_CTYPEundLC_COLLATE) öffnen Siepostgres.exein 32-Bit Dependency Walker und stellen Sie sicher, dass es anzeigt, dassMSVCR100.DLLgeladen wird aus dem PostgreSQL-binVerzeichnis. - Wenn alles gut funktioniert, kopieren Sie die gepatchte DLL in die Produktions-PostgreSQL-
binVerzeichnis und Neustart.
- wenn Ihre Abfrage immer noch nicht funktioniert (stellen Sie sicher, dass Ihre Datenbank mit
ABER BEACHTEN SIE, dass in dem Moment, in dem Sie die Daten vom Ubuntu-System oder vom gepatchten Windows-System auf ein ungepatchtes Windows-System verschieben, das Problem erneut auftritt und Sie diese Daten möglicherweise nicht wieder auf Ubuntu importieren können, wenn die Windows-Instanz Duplikate einführte ein citext Feld oder in einem UPPER /LOWER -basierter Funktionsindex.