Der Unicode-Codepunkt 9619 ist ein Zeichen namens "Dunkler Schatten": ▓
( http://unicode-table.com/de/search/?q=9619 ).
Bei Verwendung der SQL_Latin1_General_CP1_CI_AS
Codepage Kollatierung und 1252 würde ich erwarten, dass das Umwandeln / Konvertieren dieses Unicode-Zeichens in einen Nicht-Unicode-Datentyp zu einem Fragezeichen ( ?
) führt, da die Codepage 1252 dieses Zeichen nicht zu enthalten scheint und dies anscheinend SQL Server ist Verhalten, wenn keine Konvertierung stattfinden kann.
Meine Frage lautet also: Warum konvertiert SQL Server dieses Zeichen in einen ASCII-Code 166, der "Pipe, Broken Vertical Bar" lautet : ¦
?
SELECT NCHAR(9619), CAST(NCHAR(9619) AS CHAR(1)), ASCII(CAST(NCHAR(9619) AS CHAR(1)))
sql-server
collation
encoding
unicode
Henry Lee
quelle
quelle
Antworten:
SQL Server verwendet hier keine spezielle benutzerdefinierte Logik. Für die Konvertierung werden Standardbetriebssystemdienste verwendet.
Insbesondere
sqlTsEs
ruft der SQL Server-Typ und Ausdrucksdienst ( ) die BetriebssystemroutineWideCharToMultiByte
in aufkernel32.dll
. SQL Server setzt die EingabeparameterWideCharToMultiByte
so, dass die Routine eine 'schnelle Übersetzung' durchführt. Dies ist schneller als die Anforderung, dass ein bestimmtes Standardzeichen verwendet wird, wenn keine direkte Übersetzung vorhanden ist.Die schnelle Übersetzung basiert auf der Zielcodepage, um eine optimale Anpassung für nicht übereinstimmende Zeichen durchzuführen , wie in dem Link erwähnt, den Martin Smith in einem Kommentar zur Frage angegeben hat:
Wenn die Eingabeparameter für eine schnelle Übersetzung festgelegt sind, wird
WideCharToMultiByte
der BetriebssystemdienstGetMBNoDefault
( Quelle ) aufgerufen . Die Überprüfung des SQL Server-Aufrufstapels bei der Durchführung der in der Frage angegebenen Konvertierung bestätigt Folgendes:quelle
Bei der Konvertierung von Unicode-Daten in eine bestimmte Codepage wird die sogenannte "Best-Fit" -Strategie verwendet (wie in der Antwort von @ Paul und in dem Link angegeben, den @Martin in einem Kommentar zur Frage vermerkt hat). Laut dieser MSDN-Seite für die Zeichenkodierung in .NET Framework :
Aber was genau sind diese Zuordnungen? Das MSDN - Seite verwendet die folgende angeben:
Das war jedoch nicht ganz richtig. Möglicherweise sind die "Strategien" zur Bestimmung der Zuordnungen nicht genau dokumentiert. OK. Die Zuordnungen selbst sind jedoch dokumentiert, nur nicht an den am einfachsten zu findenden Orten.
Dank Microsoft, das die Dokumentation auf GitHub verschoben hat, wird auf dieser Seite nun Folgendes angezeigt (weil ich sie aktualisiert habe 😸):
Wenn Sie zur folgenden URL gehen, wird eine Liste mit mehreren Dateien angezeigt, die jeweils nach der Codepage benannt sind, der Unicode-Zeichen zugeordnet sind:
ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/
Die meisten Dateien wurden zuletzt am 04.10.2006 aktualisiert (oder zumindest dort abgelegt), und eine davon wurde am 14.03.2012 aktualisiert. Der erste Teil dieser Dateien ordnet ASCII-Codes einem entsprechenden Unicode-Codepunkt zu. Der zweite Teil jeder Datei ordnet die Unicode-Zeichen jedoch ihren ASCII-Äquivalenten zu.
Ich habe ein Testskript geschrieben, das die Codezuordnungen verwendet, um zu überprüfen, ob SQL Server diese Zuordnungen wirklich verwendet. Dies kann durch Beantwortung dieser beiden Fragen festgestellt werden:
?
Zeichen.Das Testskript ist zu lang, um es hier zu platzieren. Deshalb habe ich es auf Pastebin veröffentlicht unter:
Zuordnungen von Unicode zu Codepage in SQL Server
Durch Ausführen des Skripts wird angezeigt, dass die Antwort auf die erste Frage oben "Ja" lautet (was bedeutet, dass alle bereitgestellten Zuordnungen eingehalten werden). Es wird auch gezeigt, dass die Antwort auf die zweite Frage "Nein" lautet (was bedeutet, dass keiner der nicht zugeordneten Codepunkte in etwas anderes als das Zeichen für "unbekannt" umgewandelt wird). Daher ist diese Zuordnungsdatei sehr genau :-).
quelle