Titik kode Unicode 9619 adalah karakter yang disebut "Naungan gelap": ▓
( http://unicode-table.com/en/search/?q=9619 ).
Menggunakan SQL_Latin1_General_CP1_CI_AS
halaman kode collation dan 1252, saya akan berharap bahwa casting / konversi karakter Unicode ke tipe data non-Unicode akan menghasilkan tanda tanya ( ?
) karena kode halaman 1252 tampaknya tidak mengandung karakter ini dan ini tampaknya SQL Server perilaku saat konversi tidak dapat dilakukan.
Jadi pertanyaan saya adalah: mengapa SQL Server mengubah karakter ini menjadi kode ASCII 166 yang merupakan "Pipa, Rusak batang vertikal" ¦
:?
SELECT NCHAR(9619), CAST(NCHAR(9619) AS CHAR(1)), ASCII(CAST(NCHAR(9619) AS CHAR(1)))
sql-server
collation
encoding
unicode
Henry Lee
sumber
sumber
Jawaban:
SQL Server tidak menggunakan logika khusus khusus di sini; itu menggunakan layanan sistem operasi standar untuk melakukan konversi.
Secara khusus, SQL Server jenis dan layanan ekspresi (
sqlTsEs
) panggilan ke rutinitas OSWideCharToMultiByte
dikernel32.dll
. SQL Server mengatur parameter inputWideCharToMultiByte
sedemikian rupa sehingga rutin melakukan 'terjemahan cepat'. Ini lebih cepat daripada meminta karakter default tertentu digunakan ketika tidak ada terjemahan langsung.Terjemahan cepat bergantung pada halaman kode target untuk melakukan pemetaan paling cocok untuk setiap karakter yang tidak cocok, seperti yang disebutkan dalam tautan Martin Smith yang disediakan dalam komentar untuk pertanyaan:
Ketika parameter input ditetapkan untuk terjemahan cepat,
WideCharToMultiByte
panggil layanan OSGetMBNoDefault
( sumber ). Memeriksa tumpukan panggilan SQL Server ketika melakukan konversi yang ditentukan dalam pertanyaan mengkonfirmasi ini:sumber
Konversi dari data Unicode ke Halaman Kode tertentu menggunakan apa yang dikenal sebagai strategi "Paling Cocok" (seperti yang tercantum dalam jawaban @ Paul dan di tautan yang dicatat oleh @Martin dalam komentar pada Pertanyaan). Menurut halaman MSDN untuk Pengodean Karakter di .NET Framework :
Tapi apa sebenarnya pemetaan ini? Halaman MSDN yang digunakan untuk menyatakan sebagai berikut:
Namun, itu tidak sepenuhnya benar. Mungkin "strategi" untuk menentukan pemetaan tidak terdokumentasi dengan tepat. Baik. Tapi, pemetaan sendiri yang didokumentasikan, hanya saja tidak dalam termudah tempat untuk menemukan.
Jadi, berkat Microsoft memindahkan dokumentasi ke GitHub, halaman itu sekarang menyatakan yang berikut (karena saya memperbaruinya 😸):
Jika Anda membuka URL berikut, Anda akan melihat daftar beberapa file, masing-masing diberi nama untuk Halaman Kode yang memetakan karakter Unicode ke:
ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/
Sebagian besar file terakhir diperbarui (atau setidaknya ditempatkan di sana) pada 2006-10-04, dan salah satunya diperbarui pada 2012-03-14. Bagian pertama dari file-file tersebut memetakan kode ASCII ke dalam Unicode Code Point yang setara. Tetapi bagian kedua dari setiap file memetakan karakter Unicode ke "padanan" ASCII mereka.
Saya menulis skrip pengujian yang menggunakan pemetaan Kode untuk memeriksa apakah SQL Server benar-benar menggunakan pemetaan tersebut. Itu dapat ditentukan dengan menjawab dua pertanyaan ini:
?
"?Script tes terlalu panjang untuk ditempatkan di sini, jadi saya mempostingnya di Pastebin di:
Pemetaan Unicode ke Halaman Kode di SQL Server
Menjalankan skrip akan menunjukkan bahwa jawaban untuk pertanyaan pertama di atas adalah "Ya" (artinya semua pemetaan yang disediakan dipatuhi). Ini juga akan menunjukkan bahwa jawaban untuk pertanyaan kedua adalah "Tidak" (artinya, tidak ada Poin Kode yang tidak dipetakan yang dikonversi menjadi apa pun selain karakter untuk "tidak dikenal"). Karenanya, file pemetaan itu sangat akurat :-).
sumber