Czy istnieje sposób na zdefiniowanie kolumny/pola SQL Server jako posiadającego kodowanie UTF-8?
Nie, jedynym kodowaniem Unicode w SQL Server jest UTF-16 Little Endian, tak jak NCHAR
, NVARCHAR
, NTEXT
(przestarzałe od SQL Server 2005, więc nie używaj tego w nowych programach; poza tym jest do bani w porównaniu z NVARCHAR(MAX)
w każdym razie) i XML
obsługiwane są typy danych. Nie masz wyboru kodowania Unicode, jak pozwalają niektóre inne RDBMS.
Możesz wstawić kod XML zakodowany w UTF-8 do SQL Server, pod warunkiem przestrzegania tych trzech zasad:
- Przychodzący ciąg musi mieć typ danych
VARCHAR
, a nieNVARCHAR
(jakoNVARCHAR
to zawsze UTF-16 Little Endian, stąd błąd dotyczący niemożności zmiany kodowania). - XML zawiera deklarację XML, która wyraźnie stwierdza, że kodowanie XML to rzeczywiście UTF-8:
<?xml version="1.0" encoding="UTF-8" ?>
. - Sekwencja bajtów musi być rzeczywistymi bajtami UTF-8.
Na przykład, możemy zaimportować zakodowany w UTF-8 dokument XML zawierający emoji krzyczącej twarzy (i możemy uzyskać sekwencję bajtów UTF-8 dla tego znaku uzupełniającego, klikając ten link):
SET NOCOUNT ON;
DECLARE @XML XML = '<?xml version="1.0" encoding="utf-8"?><root><test>'
+ CHAR(0xF0) + CHAR(0x9F) + CHAR(0x98) + CHAR(0xB1)
+ '</test></root>';
SELECT @XML;
PRINT CONVERT(NVARCHAR(MAX), @XML);
Zwroty (w zakładkach „Wyniki” i „Wiadomości”):
<root><test>😱</test></root>
Wspomniałeś w komentarzu do odpowiedzi @Shnugo:
Nie miałem problemów z wstawianiem strumieni zakodowanych utf-8 z nagłówkiem utf-8 do kolumny SQL Server 2013 NVARCHAR. Czy byłby jakiś ukryty problem?
Nie, nie zapisałeś niczego zakodowanego w UTF-8 w NVARCHAR
kolumna (poza tym nie ma wersji SQL Server 2013, ale to chyba tylko literówka). NVARCHAR
jest tylko UTF-16 Little Endian. Najprawdopodobniej twój strumień UTF-8 został przekonwertowany do UTF-16 LE przez sterownik bazy danych podczas przesyłania do SQL Server. Jest to to samo kodowanie, którego użyłaby kolumna XML, ale kolumna XML próbowałaby przekonwertować strumień z UTF-8 na UTF-16, ale nie powiodła się, ponieważ była już w UTF-16. Oznacza to również, że w momencie wyjścia z SQL Server, dokument XML przechowywany w NVARCHAR
kolumna nadal miałaby deklarację XML stwierdzającą, że kodowanie to UTF-8, ale zdecydowanie nie jest to UTF-8.
Jeśli bezwzględnie potrzebujesz danych w UTF-8, ponieważ nie chcesz konwertować UTF-16 LE wychodzącego z SQL Server XML
lub NVARCHAR
w UTF-8, wtedy nie masz innego wyjścia, jak przechowywać dane jako VARBINARY(MAX)
.