Ich habe eine Tabelle mit einer Varchar-Spalte. Es sind Marken- (™), Copyright- (©) und andere Unicode-Zeichen zulässig (siehe unten).
Create table VarcharUnicodeCheck
(
col1 varchar(100)
)
insert into VarcharUnicodeCheck (col1) values ('MyCompany')
insert into VarcharUnicodeCheck (col1) values ('MyCompany™')
insert into VarcharUnicodeCheck (col1) values ('MyCompany░')
insert into VarcharUnicodeCheck (col1) values ('MyCompanyï')
insert into VarcharUnicodeCheck (col1) values ('MyCompany')
select * from VarcharUnicodeCheck
Die Definition von varchar besagt jedoch, dass Nicht-Unicode-Zeichenfolgendaten zulässig sind. Die Symbole Trademark (™) und Registered (®) sind jedoch Unicode- Zeichen. Widerspricht die Definition der Eigenschaft des Datentyps varchar? Ich habe ein paar Links wie den ersten und den zweiten gelesen . Trotzdem konnte ich nicht verstehen, warum es Unicode-Zeichenfolgen zulässt, wenn die Definition besagt, dass es nur Werte zulässt, die keine Unicode-Zeichenfolgen sind.
Antworten:
Du liegst hier falsch. Ihre Zeichenfolgen enthalten nur
ascii
Zeichen.Hier ist ein einfacher Test, der Ihnen zeigt, dass Ihre Charaktere alle ASCII-Zeichen sind (+ einige
extended ascii
mit ASCII-Codes zwischen 128 und 255):Hier können Sie deutlich sehen, dass alle Ihre Zeichen 1-Byte-codiert sind:
Ja, es handelt sich nicht um reine ASCII- Zeichen, sondern um Extended ASCII .
Hier zeige ich Ihnen echte Unicode-Zeichen
Trademark(™)
und deren Code und Binärdarstellung:Schließlich können Sie sehen, dass das
Trademark(™)
Unicode-Zeichen 8482-Code und nicht 153 hat:quelle
Ö
) eingenommen, und in ISO-8859-1 (manchmal als Latin1 bezeichnet) ist es ein Steuercode ohne druckbare Darstellung. Sofern Sie nicht wissen, dass Sie immer dieselbe Codepage verwenden, ist es sicherer, sich an ANSI-Zeichen (127 oder weniger) zu halten oder Unicode-Typen zu verwenden. Codepage 1252 ist in SQL Server am häufigsten, aber keineswegs allgegenwärtig.Ich stimme den Kommentaren zu, dass "Extended ASCII" ein wirklich schlechter Begriff ist, der eigentlich eine Codepage bedeutet, die Zeichen / Codepunkte im Bereich von 128 bis 255 über den von ASCII definierten Standardbereich von 0 bis 127 Codepunkten hinaus abbildet.
SQL Server unterstützt viele Codepages über Kollatierungen. Nicht-ASCII-Zeichen können in varchar gespeichert werden, solange die zugrunde liegende Kollatierung das Zeichen unterstützt.
Das Zeichen '™' kann in varchar / char-Spalten gespeichert werden, wenn die SQL Server-Sortierungscodeseite 1250 oder höher ist. Die folgende Abfrage listet Folgendes auf:
Nur eine Teilmenge davon unterstützt jedoch auch das Zeichen "©", sodass die Spaltensortierung eine der folgenden sein muss, um beide zu unterstützen:
quelle
Die anderen Antworten sind zwar nicht falsch, aber ich denke, es würde helfen, auf eine Verwirrung in der Basisterminologie hinzuweisen. Ich habe im obigen Zitat zwei Wörter aus der Frage als Beispiel für diese Verwirrung hervorgehoben. Wenn in der SQL Server-Dokumentation von Unicode- und Nicht-Unicode- Daten die Rede ist , handelt es sich nicht um die Zeichen . Sie sprechen von den Bytefolgen, die bestimmte Zeichen darstellen. Der Hauptunterschied zwischen den Unicode - Typen (
NCHAR
,NVARCHAR
,XML
, und die veralteten / ÜbelNTEXT
) und dem nicht-Unicode - Typen (CHAR
,VARCHAR
und die veralteten / ÜbelTEXT
) ist , was Arten von Bytefolgen sie speichern können.Die Nicht-Unicode-Typen speichern eine von mehreren 8-Bit-Codierungen, während die Unicode-Typen eine einzige 16-Bit-Unicode-Codierung speichern: UTF-16 Little Endian. Wie die anderen Antworten bereits erwähnt haben, hängt es von der Codepage ab, die durch die Sortierung bestimmt wird, welche Zeichen in einer 8-Bit- / Nicht-Unicode-Codierung gespeichert werden können. Während andere festgestellt haben, dass der Bytewert eines "Zeichens" von Codepage zu Codepage variieren kann, kann der Bytewert sogar innerhalb derselben Codepage variieren, wenn es sich um eine der mehreren EBCDIC-Codepages handelt (Variationen von Windows-Codepages). 1252), die nur in älteren Versionen zu finden sind, sollten nicht unbedingt für SQL Server-Kollatierungen verwendet werden (dh solche mit Namen, die mit beginnen
SQL_
).Daher ist die Definition korrekt: Alle Zeichen, die Sie in einem Nicht-Unicode-Typ speichern können, sind immer 8-Bit-Zeichen (auch wenn sie zwei 8-Bit-Werte in Kombination als ein einziges "Zeichen" verwenden). Byte Character Set / DBCS-Codepages berücksichtigen). Und die Unicode-Datentypen sind immer 16-Bit, auch wenn sie manchmal zwei 16-Bit-Werte in Kombination als ein einzelnes "Zeichen" verwenden (dh ein Ersatzpaar, das wiederum ein Zusatzzeichen darstellt).
UND, da SQL Server die UTF-8-Codierung für
VARCHAR
undCHAR
Datentypen ab SQL Server 2019 nativ unterstützt ,VARCHAR
kann nicht mehr als "Nicht-Unicode" bezeichnet werden. Ab der ersten öffentlichen Betaversion von SQL Server 2019 im September 2018 sollten wir vonVARCHAR
einem "8-Bit-Datentyp" sprechen, auch wenn es sich um Versionen vor SQL Server 2019 handelt. Diese Terminologie gilt für alle vier Typen von Kodierungen, die verwendet werden können mitVARCHAR
:Lediglich der
TEXT
Datentyp (der ab SQL Server 2005 veraltet ist, verwenden Sie ihn also nicht mehr) ist "Nicht-Unicode", dies ist jedoch nur eine technische Angelegenheit, und es ist korrekt, ihn als "8-Bit-Datentyp" zu bezeichnen.NVARCHAR
,NCHAR
UndNTEXT
kann als „UTF-16“ oder „16-Bit - Datentyp“ bezeichnet werden. Ich glaube, Oracle verwendet die Terminologie von "Unicode-only" fürNVARCHAR
, aber das schließt nicht eindeutig die Möglichkeit aus, UTF-8 (auch eine Unicode-Codierung) zu verwenden, die nicht funktioniert die ersten beiden Möglichkeiten.Einzelheiten zu den neuen UTF-8-Codierungen finden Sie in meinem Beitrag:
Native UTF-8-Unterstützung in SQL Server 2019: Retter oder falscher Prophet?
PS Ich arbeite mich langsam durch die Aktualisierung der SQL Server-Dokumentation, um diese Änderungen zu berücksichtigen.
PPS Microsoft hat bereits einige Seiten mit UTF-8-Informationen aktualisiert, einschließlich der Char- und Varchar- Dokumentation, auf die in der Frage verwiesen wird. Es enthält nicht länger die Phrase "non-Unicode". Aber das ist nur eine FYI; Dies ändert nichts an der Frage, da es sich um Nicht-Unicode-Codierungen handelt, die Zeichen enthalten, die fälschlicherweise als reine Unicode-Codierungen angesehen wurden.
quelle
Die Frage enthält ein zentrales Missverständnis darüber, was Unicode ist. Der Unicode-Zeichensatz ist zusammen mit seinen Codierungen wie UTF-8 und UTF-16 eine von vielen Möglichkeiten, Text in einem Computer darzustellen. Ziel ist es, alle anderen Zeichensätze und Codierungen zu ersetzen. Wenn "Nicht-Unicode-Daten" "Zeichen, die in Unicode nicht vorhanden sind" bedeuten, könnte keiner der in dieser Antwort verwendeten Texte in diesem Typ gespeichert werden, da alle Buchstaben des lateinischen Alphabets und die im Englischen üblichen Interpunktionen verwendet werden in Unicode enthalten.
Textdarstellungen können grob in zwei Teilen betrachtet werden: einem Zeichensatz, der die verschiedenen Zeichen (Buchstaben, Ziffern, Symbole usw.) auf einem Referenzdiagramm den Zahlen zuordnet; und eine Codierung, die diese Zahlen als Bitmuster darstellt (auf der Festplatte, über eine Netzwerkverbindung usw.). Hier geht es hauptsächlich um den ersten Teil: Welche Zeichen sind in den Diagrammen für einen bestimmten Zeichensatz aufgeführt?
Da Unicode für jedes Zeichen auf der Welt Zahlen (die als "Codepunkte" bezeichnet werden) anstrebt, beziehen sich Verweise wie Wikipedia häufig auf die Unicode-Position eines Zeichens als Standard-Referenzinformation. Dies bedeutet jedoch nicht, dass andere Zeichensätze keine Zuordnung für dasselbe Zeichen haben.
Einer der ältesten und einfachsten Zeichensätze (und Kodierungen), die noch verwendet werden, ist ASCII, das Zuordnungen für 128 verschiedene Zeichen (0 bis 127) enthält, da jedes Zeichen mit 7 Bits kodiert wird. Seit diesem schließen viele akzentuierten Zeichen und Symbolen gemeinsamer Verwenden später Codierungen 8 Bits, und ordnen die gleichen ersten 128 Zeichen, zusätzlich zu dem Zeichensatz von Positionen 128 bis 255. Bemerkenswert unter diesen sind Füllung der Standard ISO 8859-1 und ISO 8859- 15 und den Microsoft-spezifischen Windows-Code Seite 1252 .
Zurück zu MS SQL Server: Eine "Unicode-Zeichenfolge", wie sie in einer
nchar
,nvarchar
oderntext
Spalte gespeichert ist , kann alle im Unicode-Zeichensatz zugeordneten Zeichen darstellen, da zum Speichern der Daten eine Unicode-Codierung verwendet wird. Eine "Nicht-Unicode-Zeichenfolge", wie sie in einerchar
,varchar
odertext
Spalte gespeichert ist , kann nur die Zeichen darstellen, die in einer anderen Codierung zugeordnet sind . Alles, was Sie in einer Nicht-Unicode-Spalte speichern können, kann auch in einer Unicode-Spalte gespeichert werden, aber nicht umgekehrt.Um genau zu wissen, welche Zeichen Sie speichern können, müssen Sie die verwendete "Kollatierung" kennen, die vorgibt, was Microsoft als "Codepage" bezeichnet, wie auf dieser Microsoft-Referenzseite erläutert . In Ihrem Fall verwenden Sie wahrscheinlich den sehr verbreiteten Code, den ich bereits erwähnt habe.
Die von Ihnen genannten Zeichen sind sowohl in Unicode als auch in Code Page 1252 enthalten:
quelle