Die Flexperten Herrlich & Ramuschkat

ColdFusion, Unicode und MS SQL Server

Unser Kollege Dirk teilte gerade folgendes mit: falls Ihr mal das Problem haben solltet, dass Unicode (utf-8 oder utf-16) unter Verwendung von ColdFusion nicht korrekt in einer MS SQL Server DB gespeichert hier ein paar Tipps.

Auffallen tut das Problem dadurch, dass in den Spalten nicht der Text steht, der da eigentlich rein soll. Das betrifft natürlich “nur” Zeichen, die außerhalb der von uns normalerweise verwendeten Zeichentabelle liegen, also besondere Umlaute, aber z.B. auch die griechischen oder kyrillischen Buchstaben.

1) ab SQL Server 2000 unterstützt MSSQL Unicode (genauer UCS-2, was letztlich UTF-16 entspricht – die Unterschiede sind akademischer Natur). Damit aber Unicode codierter Text auch korrekt in der DB gespeichert wird, müssen die Spalten in der Tabelle von Typ nvarchar(n) bzw nvarchar(max) sein (letzteres ab SQL 2005).

Wichtig dabei: bei nvarchar(n) kann man maximal 4000 Zeichen speichern, bei nvarchar(max) ist bei 2 GByte Schluß (max ist tatsächlich der richtige Wert, mehr Infos auch bei http://msdn.microsoft.com/en-us/library/ms186939.aspx)

2) wenn Ihr den bei CF beiliegenden SQL Server Treiber für die Datenquelle verwendet, dann muss unbedingt in den Advanced Settings der Datasource das Häkchen bei “Enable High ASCII characters and Unicode for data sources configured for non-Latin characters” gesetzt werden, sonst entsteht beim INSERT/UPDATE nur Datenmüll!

3) Falls die Daten über eine CFML eingegeben (z.B. ein Form) werden und dann per CFQUERY gespeichert werden, muss  oben in der CFML Seite <cfprocessingdirective pageencoding=”utf-8″ /> gesetzt werden. Ggf. dann auch noch per setEncoding(“form”, “utf-8”) das Encoding auf dem Form scope setzen.

Falls die Daten von Flex über AMF/Remoting an eine CFC geschickt wurden, dann muss man das nicht explizit tun, da der Flash Player alle Strings UTF-8 codiert.

4) Beim INSERT / UPDATE entweder jeder Spalte ein N voranstellen, also z.B.

<cfset test = "Колбасный салат">

<cfquery>
  update test set title = N'#test#'
</cfquery>

oder mit cfqueryparam arbeiten

<cfset test = "Колбасный салат">

<cfquery>
  update test
  set title =  <cfqueryparam cfsqltype="cf_sql_varchar" value="#test#">
</cfquery>

6 Kommentare

  1. Hannes Kiessling am 20. November 2010

    Moin,

    bei mir klappt das so leider nicht, ich arbeite an einem Projekt für eine Ortsdatenbank auf Basis der OpenGeoDB für Orte in Russland, Ukraine und Weißrussland.

    Bei mir wird aus Харькoв – %0@L:o2

    Gruß aus Nordfriesland

    Hannes

  2. FSemrau am 22. November 2010

    Hallo Hannes,

    kommt der String in der Datenbank falsch an oder ist bloß die Ausgabe falsch codiert? Was sagt denn das Management Studio, bzw. was spuckt das denn aus?

    Gruß,
    Frank

  3. Hannes Kiessling am 23. November 2010

    Hallo,

    nee der String in der DB steht so drin wie er ausgegeben wird, also Müll…
    Die DB ist UTF-8 und in der Application.cfm steht

    Gruß

  4. Hannes Kiessling am 24. November 2010

    Hatte er nicht mitgenommen…

    cfcontent type=”text/html; charset=UTF-8″
    cfset setEncoding(“form”, “UTF-8”)
    cfset setEncoding(“url”, “UTF-8”)

  5. FSemrau am 24. November 2010

    Ok, und welchen SQL-Teriber verwendest Du mit CF und MSSQL? Den Standardtreiber, der bei Coldfusion dabei ist? Hast Du da die Einstellungen (“Enable High ASCII…”) gemacht (siehe oben Punkt 2)? Dirk erwähnte ja, das es durch nicht-aktivieren zu Datenmüll in den Spalten kommt. Ansonsten mußt Du nur noch den Datentyp beim INSERT/UPDTAE beachten, wenn Du kein cfqueryparam verwendest. Dann sollte das klappen…

  6. Hannes Kiessling am 29. November 2010

    Hallo,

    vielen Dank, ja, der DB-Treiber war die Ursache!

    Gruß aus Nordfriesland

    Hannes

Einen Kommentar schreiben