Mam tabelę z kolumną varchar. Pozwala na znak towarowy (™), prawa autorskie (©) i inne znaki Unicode, jak pokazano poniżej.
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
Ale definicja varchar mówi, że pozwala na dane łańcuchowe inne niż Unicode. Ale symbole znaków towarowych (™) i zarejestrowanych (®) są znakami Unicode . Czy definicja jest sprzeczna z właściwością typu danych varchar? Przeczytałem kilka linków, takich jak pierwszy i drugi . Ale nadal nie mogłem zrozumieć, dlaczego dopuszcza ciąg znaków Unicode, gdy definicja mówi, że dopuszcza tylko wartości łańcuchów innych niż Unicode.
sql-server
datatypes
character-set
encoding
unicode
siedmiodniowa żałoba
źródło
źródło
Odpowiedzi:
Mylisz się tutaj. Twoje ciągi zawierają tylko
ascii
znaki.Oto prosty test, który pokazuje, że wszystkie twoje postacie są ascii (+ niektóre
extended ascii
z kodami ascii między 128 a 255):Tutaj możesz wyraźnie zobaczyć, że wszystkie twoje postacie są kodowane 1-bajtowo:
Tak, nie są to czyste znaki ascii, ale są rozszerzonymi ASCII .
Tutaj pokazuję ci prawdziwy znak Unicode
Trademark(™)
oraz jego kod i reprezentację binarną:Wreszcie możesz zobaczyć, że
Trademark(™)
znak Unicode ma kod 8482, a nie 153:źródło
Ö
), a na ISO-8859-1 (czasami nazywany Latin1) jest to kod kontrolny bez reprezentacji do wydrukowania. Jeśli nie wiesz , że zawsze będziesz używać tej samej strony kodowej, bezpieczniej jest trzymać się znaków ANSI (127 lub mniej) lub używać typów Unicode. Strona kodowa 1252 jest najczęstsza w SQL Server, ale daleka od wszechobecności.Z komentarzy zgadzam się, że „rozszerzony ASCII” to naprawdę zły termin, który w rzeczywistości oznacza stronę kodową, która odwzorowuje znaki / punkty kodowe w zakresie 128-255, poza standardowym zakresem punktów kodowych 0-127 zdefiniowanym przez ASCII.
SQL Server obsługuje wiele stron kodowych poprzez sortowanie. Znaki inne niż ASCII mogą być przechowywane w varchar, o ile podstawowe zestawienie obsługuje znak.
Znak „™” może być przechowywany w kolumnach varchar / char, gdy strona kodowa sortowania programu SQL Server ma 1250 lub więcej. Poniżej znajduje się zapytanie:
Ale tylko ich podzbiór obsługuje również znak „©”, więc sortowanie kolumn musi być jednym z następujących, aby obsługiwać oba:
źródło
Podczas gdy inne odpowiedzi nie są niepoprawne, myślę, że pomogłoby to wskazać na pomyłkę w podstawowej terminologii. Podkreśliłem dwa słowa w powyższym cytacie z pytania jako przykład tego zamieszania. Kiedy dokumentacja SQL Server mówi o Unicode i non-Unicode danych , są one nie mówić o znaki . Mówią o sekwencjach bajtów reprezentujących określone znaki. Podstawowa różnica między typami Unicode (
NCHAR
,NVARCHAR
,XML
, a przestarzałe / złaNTEXT
) i typami non-Unicode (CHAR
,VARCHAR
, a przestarzałe / złaTEXT
) jest tym, co rodzaje sekwencji bajtów mogą przechowywać.Typy inne niż Unicode przechowują jedno z kilku 8-bitowych kodowań, podczas gdy typy Unicode przechowują pojedyncze 16-bitowe kodowanie Unicode: UTF-16 Little Endian. Jak wspomniano w innych odpowiedziach, które znaki mogą być przechowywane w kodowaniu 8-bitowym / innym niż Unicode, zależy od strony kodowej, która jest określona przez sortowanie. Podczas gdy inni zauważyli, że wartość bajtu „znaku” może się różnić w zależności od stron kodowych, na których się znajduje, wartość bajtu może nawet różnić się w obrębie tej samej strony kodowej w przypadku jednej z kilku stron kodowych EBCDIC (odmiany systemu Windows- 1252), które można znaleźć tylko w starszych, nie należy tak naprawdę używać kolacji SQL Server (tj. Tych, których nazwy zaczynają się od
SQL_
).Dlatego definicja jest dokładna: wszystkie znaki, które możesz przechowywać w typie innym niż Unicode, są zawsze 8-bitowe (nawet jeśli używają dwóch 8-bitowych wartości w kombinacji jako pojedynczego „znaku”, co właśnie Double- Zestaw znaków bajtów / strony kodowe DBCS pozwalają na). A typy danych Unicode są zawsze 16-bitowe, nawet jeśli czasami używają dwóch 16-bitowych wartości w kombinacji jako pojedynczego „znaku” (tj. Pary zastępczej, która z kolei reprezentuje znak uzupełniający).
ORAZ ze względu na natywną obsługę SQL Server kodowania UTF-8
VARCHAR
iCHAR
typów danych od SQL Server 2019,VARCHAR
nie może być dłużej określany jako „inny niż Unicode”. Począwszy od pierwszej publicznej wersji beta programu SQL Server 2019 we wrześniu 2018 r., Powinniśmy nazywać goVARCHAR
„8-bitowym typem danych”, nawet jeśli mówimy o wersjach wcześniejszych niż SQL Server 2019. Ta terminologia obowiązuje w przypadku wszystkich 4 typów kodowań, których można używać zVARCHAR
:Tylko
TEXT
typ danych (przestarzały od SQL Server 2005, więc nie używaj go) jest „inny niż Unicode”, ale to tylko kwestia techniczna, a określenie go jako „typ danych 8-bitowych” jest dokładne.NVARCHAR
,NCHAR
iNTEXT
może być określany jako „UTF-16” lub „16-bitowy typ danych”. Wierzę, że Oracle używa terminologii „tylko Unicode”NVARCHAR
, ale nie wyklucza to wyraźnie możliwości użycia UTF-8 (również kodowania Unicode), co nie będzie działać, więc prawdopodobnie najlepiej trzymać się dwie pierwsze opcje.Szczegółowe informacje na temat nowych kodowań UTF-8 znajdują się w moim poście:
Natywne wsparcie UTF-8 w SQL Server 2019: Zbawiciel czy fałszywy prorok?
PS Powoli pracuję nad aktualizacją dokumentacji SQL Server, aby odzwierciedlić te zmiany.
PPS Microsoft zaktualizował już niektóre strony o informacje UTF-8, w tym dokumentację char i varchar wymienioną w pytaniu. Nie zawiera już frazy „non-Unicode”. Ale to tylko informacja finansowa; nie zmienia to pytania, ponieważ dotyczy to kodowań innych niż Unicode zawierających znaki, które błędnie uważano za tylko Unicode.
źródło
Pytanie zawiera błędne przekonanie o tym, czym jest Unicode. Zestaw znaków Unicode, wraz z jego kodowaniem, takim jak UTF-8 i UTF-16, jest jednym z wielu sposobów przedstawiania tekstu w komputerze, a jego celem jest zastąpienie wszystkich innych zestawów znaków i kodowań. Jeśli „dane inne niż Unicode” oznaczają „znaki nieobecne w Unicode”, to żaden tekst użyty w tej odpowiedzi nie może być zapisany w tym typie, ponieważ wszystkie litery alfabetu łacińskiego i powszechne znaki interpunkcyjne używane w codziennym języku angielskim są zawarte w Unicode.
Reprezentacje tekstowe można ogólnie rozpatrywać w dwóch częściach: zestaw znaków odwzorowujący różne znaki (litery, cyfry, symbole itp.) Na liczby na mapie odniesienia; oraz kodowanie reprezentujące te liczby jako wzorce bitów (na dysku, przez połączenie sieciowe itp.). Tutaj zajmujemy się głównie pierwszą częścią: które postacie są wymienione na listach przebojów dla określonego zestawu znaków.
Ponieważ Unicode dąży do posiadania liczb (które nazywają „punktami kodowymi”) dla każdego znaku na świecie, odniesienia takie jak Wikipedia często odnoszą się do położenia znaku w Unicode jako standardowej informacji. Nie oznacza to jednak, że inne zestawy znaków również nie mają mapowania dla tej samej postaci.
Jednym z najstarszych i najprostszych wciąż używanych zestawów znaków (i kodowania) jest ASCII, który zawiera mapowania 128 różnych znaków (od 0 do 127), ponieważ używa 7 bitów do kodowania każdego znaku. Ponieważ wyklucza to wiele znaków akcentowanych i wspólnych symboli, późniejsze kodowania wykorzystują 8 bitów i odwzorowują te same pierwsze 128 znaków, dodając do zestawu znaków poprzez wypełnienie pozycji od 128 do 255. Wśród nich godne uwagi są standardowe ISO 8859-1 i ISO 8859- 15 oraz specyficzną dla Microsoft stronę Windows Code Page 1252 .
Tak więc, aby wrócić do MS SQL Server: a „ciąg Unicode”, jak przechowywane w
nchar
,nvarchar
lubntext
kolumnę, może reprezentować wszystkie znaki odwzorowanych w zestawie znaków Unicode, ponieważ korzysta z kodowania Unicode do przechowywania danych. A „ciąg non-Unicode”, jak przechowywane wchar
,varchar
lubtext
kolumnie, może reprezentować tylko znaki odwzorowywane w innym kodowaniu . Wszystko, co możesz przechowywać w kolumnie innej niż Unicode, może być również przechowywane w kolumnie Unicode, ale nie odwrotnie.Aby dokładnie wiedzieć, jakie znaki możesz przechowywać, musisz znać „zestawienie” w użyciu, które określa, co Microsoft określa jako „stronę kodową”, jak wyjaśniono na tej stronie odniesienia Microsoft . Prawdopodobnie w twoim przypadku używasz bardzo popularnego kodu Page 1252, o którym wspominałem wcześniej.
Znaki, które wymieniłeś istnieją zarówno w Unicode, jak i Code Page 1252:
źródło