Chcę ustawić zmienną łańcuchową Unicode na określony znak na podstawie jego punktu kodowego Unicode.
Chcę użyć punktu kodu poza 65535, ale baza danych SQL Server 2008 R2 ma zestawienie SQL_Latin1_General_CP1_CI_AS
.
Według dokumentacji Nchar Microsoftu The NCHAR
funkcja przyjmuje liczbę całkowitą, co następuje:
wyrażenie_całkowite
Gdy zestawienie bazy danych nie zawiera flagi znaku uzupełniającego (SC), jest to dodatnia liczba całkowita od 0 do 65535 (od 0 do 0xFFFF). Jeśli podano wartość spoza tego zakresu, zwracana jest wartość NULL. Aby uzyskać więcej informacji o znakach uzupełniających, zobacz Obsługa sortowania i Unicode.
Gdy zestawianie bazy danych obsługuje flagę znaku uzupełniającego (SC), jest to dodatnia liczba całkowita od 0 do 1114111 (od 0 do 0x10FFFF). Jeśli podano wartość spoza tego zakresu, zwracana jest wartość NULL.
Więc ten kod:
SELECT NCHAR(128512);
Zwraca NULL
w tej bazie danych.
Chciałbym, aby zwrócił to samo:
SELECT N'😀';
Jak ustawić zmienną łańcuchową Unicode (np. Nvarchar) na emoji za pomocą kodu (bez użycia rzeczywistego znaku emoji) w bazie danych, w której zestawienie „nie zawiera flagi znaku uzupełniającego (SC)”?
Pełna lista punktów kodu emoji Unicode
(Ostatecznie chcę, aby jakakolwiek postać działała. Po prostu wybrałem emoji dla ułatwienia wyszukiwania.)
(Chociaż serwerem jest SQL Server 2008 R2, jestem również ciekawy rozwiązań dla późniejszych wersji).
Zakładając, że nie ma mowy, czy mogę odwoływać się do wbudowanej funkcji zdefiniowanej przez użytkownika w innej bazie danych, która miała odpowiednie zestawienie?
Jak znaleźć zestawienie z flagą „znak uzupełniający”?
Nie zwraca żadnych danych na naszym serwerze:
SELECT * FROM sys.fn_helpcollations()
WHERE name LIKE 'SQL%[_]SC';
Wygląda na to, że wprowadzono SQL Server 2012 Latin1_General_100_CI_AS_SC
który działałby. Czy możesz zainstalować sortowanie w starszych instancjach?
Referencje sortowania:
- Odpowiedź na jaka jest różnica między char, nchar, varchar i nvarchar w SQL Server?
- Informacje o sortowaniu znaków uzupełniających firmy Microsoft
- Lista sortowania SQL Server 2008 R2 firmy Microsoft
Czy istnieje wyjaśnienie, dlaczego, niezależnie od sortowania, SQL Server może zrozumieć i radzić sobie z rozszerzonymi znakami, z wyjątkiem perspektywy NCHAR
?
Odpowiedzi:
Kodowanie UCS-2 ma zawsze 2 bajty na znak i ma zakres od 0 do 65535 (0x0000 - 0xFFFF). UTF-16 (niezależnie od Big Endian lub Little Endian) ma zakres od 0 do 1114111 (0x0000 - 0x10FFFF). Zakres 0 - 65535 / 0x0000 - 0xFFFF dla UTF-16 wynosi 2 bajty na znak, podczas gdy zakres powyżej 65536 / 0xFFFF wynosi 4 bajty na znak.
Windows i SQL Server zaczęły od kodowania UCS-2, ponieważ były one dostępne, a UTF-16 nie został jeszcze sfinalizowany. Na szczęście jednak w projektach UCS-2 i UTF-16 było wystarczająco dużo myśli, aby odwzorowania UCS-2 były kompletnym podzbiorem odwzorowań UTF-16 (co oznacza: zakres 0 - 65535 / 0x0000 - 0xFFFF UTF-16 to UCS-2). ORAZ zakres 65536 - 1114111 (0x10000 - 0x10FFFF) UTF-16 jest skonstruowany z dwóch punktów kodowych w zakresie UCS-2 (konkretnie zakresów 0xD800 - 0xDBFF i 0xDC00 - 0xDFFF), które zostały zarezerwowane do tego celu, a poza tym nie mają znaczenie. Ta kombinacja dwóch Punktów Kodowych jest znana jako Para Zastępcza, a Pary Zastępcze reprezentują postacie spoza zakresu UCS-2, które są znane jako Postacie Uzupełniające.
Wszystkie te informacje wyjaśniają dwa aspekty danych
NVARCHAR
/ Unicode w SQL Server:NCHAR()
) nie obsługują zastępczych par / dodatkowych znaków, gdy nie jest używany charakter uzupełniający-Aware Sortowanie (SCA, czyli jeden z_SC
, lub_140_
ale nie_BIN*
w nazwie), ponieważ non-SCA Konfrontacje (zwłaszczaSQL_
Zestawienia) zostały pierwotnie zaimplementowane przed ukończeniem UTF-16 (chyba w 2000 roku). W nie-SQL_
Konfrontacje, które mają_90_
lub_100_
w ich imieniu, ale nie_SC
mają minimalne wsparcie dla znaków uzupełniające w zakresie porównywania i sortowania.NVARCHAR
/NCHAR
/XML
/,NTEXT
ponieważ UCS-2 i UTF-16 są dokładnie tymi samymi sekwencjami bajtów. Jedyną różnicą jest to, że UTF-16 korzysta z punktów kodu zastępczego do konstruowania par surogatów, a UCS-2 po prostu nie może mapować ich na żadne znaki, dlatego wydają się one wbudowanym funkcjom jako dwa nieznane znaki.Mając na uwadze te informacje podstawowe, możemy teraz przejść do szczegółowych pytań:
Może się to zdarzyć tylko wtedy, gdy bieżąca baza danych - w której wykonywane jest zapytanie - ma domyślne sortowanie, czyli uzupełniające rozpoznawanie znaków i te zostały wprowadzone w SQL Server 2012. Funkcje wbudowane, które mają parametry wejściowe ciągu, mogą mieć zapewnione sortowanie inline poprzez
COLLATE
klauzulę (tj.LEN(N'string' COLLATE Some_Collation_SC)
) i nie muszą być wykonywane w bazie danych, która ma domyślne sortowanie SCA. Jednak wbudowane funkcje, takie jakNCHAR()
akceptacjaINT
parametru wejściowego iCOLLATE
klauzula nie są poprawne w tym kontekście (dlategoNCHAR()
obsługuje tylko znaki uzupełniające, gdy bieżąca baza danych ma domyślne sortowanie, które jest dodatkowym znakiem rozpoznającym; ale jest to niepotrzebne niedogodności, które można zmienić, dlatego proszę głosować na moją sugestię:Funkcja NCHAR () powinna zawsze zwracać znak dodatkowy dla wartości 0x10000 - 0x10FFFF niezależnie od domyślnego sortowania aktywnej bazy danych ).Jak SQL Server może przechowywać i odzyskiwać dodatkowe znaki bez utraty danych, wyjaśniono w górnej części tej odpowiedzi. Ale nie jest prawdą, że
NCHAR
jest to jedyna wbudowana funkcja, która ma problemy ze znakami uzupełniającymi (gdy nie używa się sortowania SCA). Na przykładLEN(N'😀' COLLATE SQL_Latin1_General_CP1_CI_AS)
zwraca wartość 2, aLEN(N'😀' COLLATE Latin1_General_100_CI_AS_SC)
zwraca wartość 1.Jeśli przejdziesz do drugiego linku zamieszczonego w pytaniu (tj. „Informacje o sortowaniu znaków uzupełniających Microsoftu”) i przewiniesz trochę w dół, zobaczysz tabelę wbudowanych funkcji i ich zachowania w oparciu o efektywne sortowanie.
W wersji SQL Server sprzed 2012 roku nie możesz. Ale począwszy od SQL Server 2012 można użyć następującego zapytania:
Twoje zapytanie było bliskie, ale wzorzec zaczął się od,
SQL
a SQL Server Collations (tj. Te zaczynające się odSQL_
) zostały na jakiś czas przestarzałe na korzyść Windows Collations (te, które nie zaczynają się odSQL_
). Tak więc sortowaniaSQL_
nie są aktualizowane, a zatem nie mają nowszych wersji, które zawierałyby tę_SC
opcję (i począwszy od SQL Server 2017, wszystkie nowe sortowania automatycznie obsługują dodatkowe znaki i nie wymagają lub nie mają_SC
flagi; i tak, zapytanie pokazane bezpośrednio powyżej tego konta, a także pobieranie_UTF8
zestawień dodanych w SQL Server 2019).Nie, nie można zainstalować Collations w poprzedniej wersji SQL Server.
Gdy nie używasz sortowania SCA, możesz wstrzykiwać punkty kodowe powyżej 65535 / U + FFFF na dwa sposoby:
NCHAR()
parę zastępczą pod względem dwóch wywołań funkcji, każde z jedną częścią paryVARBINARY
postaci sekwencji bajtów Little Endian (tj. Odwróconej).Te dwie metody wstawiania par znaków uzupełniających / zastępczych będą działać, nawet jeśli skuteczne sortowanie jest uzupełniające z uwzględnieniem znaków i powinno działać tak samo we wszystkich wersjach programu SQL Server, przynajmniej w 2005 r. (Choć prawdopodobnie działałoby również w SQL Server 2000).
Przykład:
💩
AKTUALIZACJA
Możesz użyć następującego iTVF, aby uzyskać wartości pary zastępczej (zarówno w formie, jak
INT
iBINARY
postaci) z dowolnego punktu kodowego między 65536 - 1114111 (0x010000 - 0x10FFFF). I chociaż parametr wejściowy jest typuINT
, możesz przekazać w postaci binarnej / szesnastkowej punktu kodowego, a on domyślnie przekonwertuje na prawidłową wartość całkowitą.Korzystając z powyższej funkcji, następujące dwa zapytania:
oba zwracają:
AKTUALIZACJA 2: Jeszcze lepsza aktualizacja!
Zaadaptowałem pokazany powyżej iTVF, aby teraz zwracał 188,657 punktów kodowych, więc nie musisz dopasowywać żadnej konkretnej wartości. Oczywiście będąc TVF, możesz dodać
WHERE
klauzulę do filtrowania określonego punktu kodowego lub zakresu punktów kodowych lub „podobnych znaków” itp. I zawiera dodatkowe kolumny ze wstępnie sformatowanymi sekwencjami ucieczki, aby zbudować każdy kod punkt (zarówno BMP, jak i znaki uzupełniające) w stylu T-SQL, HTML i C (tj\xHHHH
.). Przeczytaj o tym tutaj:Wskazówka SSMS nr 3: Łatwy dostęp / badanie WSZYSTKICH znaków Unicode (tak, w tym emotikonów 😸)
źródło