Saya ingin mengatur variabel string Unicode ke karakter tertentu berdasarkan titik kode Unicode-nya.
Saya ingin menggunakan titik kode di luar 65535, tetapi database SQL Server 2008 R2 memiliki susunan SQL_Latin1_General_CP1_CI_AS
.
Menurut dokumentasi NCHAR Microsoft , NCHAR
fungsi tersebut mengambil bilangan bulat sebagai berikut:
integer_expression
Ketika susunan basis data tidak mengandung bendera karakter tambahan (SC), ini adalah bilangan bulat positif dari 0 hingga 65535 (0 hingga 0xFFFF). Jika nilai di luar rentang ini ditentukan, NULL dikembalikan. Untuk informasi lebih lanjut tentang karakter tambahan, lihat Dukungan Collation dan Unicode.
Ketika pengumpulan database mendukung bendera karakter tambahan (SC), ini adalah bilangan bulat positif dari 0 hingga 1114111 (0 hingga 0x10FFFF). Jika nilai di luar rentang ini ditentukan, NULL dikembalikan.
Jadi kode ini:
SELECT NCHAR(128512);
Kembali NULL
dalam database ini.
Saya ingin mengembalikan yang sama seperti ini:
SELECT N'😀';
Bagaimana saya bisa mengatur variabel string Unicode (misalnya nvarchar) ke emoji menggunakan kode (tanpa menggunakan karakter emoji yang sebenarnya) dalam database di mana collation "tidak mengandung flag karakter tambahan (SC)"?
Daftar lengkap poin kode emoji Unicode
(Pada akhirnya saya ingin karakter apa pun bekerja. Saya hanya memilih emoji untuk kemudahan referensi.)
(Meskipun servernya SQL Server 2008 R2, saya juga ingin tahu tentang solusi apa pun untuk versi yang lebih baru.)
Dengan asumsi bahwa tidak ada cara, dapatkah saya mereferensikan fungsi inline yang didefinisikan pengguna dalam database lain yang memiliki susunan yang sesuai?
Bagaimana cara menemukan collation yang memiliki bendera "karakter tambahan"?
Ini tidak mengembalikan catatan di server kami:
SELECT * FROM sys.fn_helpcollations()
WHERE name LIKE 'SQL%[_]SC';
Sepertinya SQL Server 2012 diperkenalkan Latin1_General_100_CI_AS_SC
yang akan bekerja. Bisakah Anda menginstal collations pada instances lama?
Referensi Penyusunan:
- Jawaban untuk Apa perbedaan antara char, nchar, varchar, dan nvarchar di SQL Server?
- Informasi Pengumpulan Karakter Tambahan Microsoft
- Daftar Collation SQL Server 2008 R2 Microsoft
Apakah ada penjelasan mengapa, terlepas dari pemeriksaan, SQL Server dapat memahami dan menangani karakter yang diperluas kecuali dari perspektif NCHAR
?
Jawaban:
Pengkodean UCS-2 selalu 2 byte per karakter dan memiliki kisaran 0 - 65535 (0x0000 - 0xFFFF). UTF-16 (terlepas dari Big Endian atau Little Endian) memiliki kisaran 0 - 1114111 (0x0000 - 0x10FFFF). Rentang 0 - 65535 / 0x0000 - 0xFFFF dari UTF-16 adalah 2 byte per karakter sedangkan kisaran di atas 65536 / 0xFFFF adalah 4 byte per karakter.
Windows dan SQL Server mulai menggunakan pengkodean UCS-2 karena sudah tersedia dan UTF-16 belum selesai. Untungnya, bagaimanapun, ada cukup pemikiran ke depan dimasukkan ke dalam desain UCS-2 dan UTF-16 bahwa pemetaan UCS-2 adalah bagian lengkap dari pemetaan UTF-16 (artinya: kisaran 0 - 65535 / 0x0000 - 0xFFFF UTF-16 adalah UCS-2). DAN, kisaran UTF-16 65536 - 1114111 (0x10000 - 0x10FFFF) dibangun dari dua Poin Kode dalam kisaran UCS-2 (kisaran 0xD800 - 0xDBFF dan 0xDC00 - 0xDFFF, khusus) yang disediakan untuk tujuan ini dan sebaliknya tidak memiliki berarti. Kombinasi dua Poin Kode ini dikenal sebagai Pasangan Pengganti, dan Pasangan Pengganti mewakili karakter di luar rentang UCS-2 yang dikenal sebagai Karakter Tambahan.
Semua informasi itu menjelaskan dua aspek
NVARCHAR
/ data Unicode di SQL Server:NCHAR()
) tidak menangani Pasangan Pengganti / Karakter Tambahan saat tidak menggunakan Collation Character-Aware Collation (SCA; yaitu satu dengan_SC
, atau_140_
tetapi tidak_BIN*
dalam nama) karena Collations non-SCA (terutamaSQL_
Collations) awalnya dilaksanakan sebelum UTF-16 selesai (sekitar tahun 2000, saya percaya). Non-SQL_
Collations yang memiliki_90_
atau_100_
atas nama mereka tetapi tidak_SC
memiliki dukungan minimal untuk Karakter Tambahan dalam hal perbandingan dan penyortiran.NVARCHAR
/NCHAR
/XML
/NTEXT
tipe data karena UCS-2 dan UTF-16 adalah urutan byte yang sama persis. Satu-satunya perbedaan adalah bahwa UTF-16 memanfaatkan titik kode pengganti untuk membangun Pasangan Pengganti, dan UCS-2 tidak dapat memetakannya ke karakter apa pun, oleh karena itu mereka muncul pada fungsi bawaan sebagai dua karakter yang tidak dikenal.Dengan mengingat informasi latar belakang itu, sekarang kita dapat melalui pertanyaan spesifik:
Itu hanya dapat terjadi jika database saat ini - di mana kueri sedang dieksekusi - memiliki Collation default yang Tambahan Karakter-Sadar, dan yang diperkenalkan di SQL Server 2012. Fungsi bawaan yang memiliki parameter input string dapat memiliki Collation yang disediakan sebaris melalui
COLLATE
klausa (yaituLEN(N'string' COLLATE Some_Collation_SC)
) dan tidak perlu dijalankan dalam Database yang memiliki Collation default SCA. Namun, fungsi bawaan sepertiNCHAR()
menerimaINT
parameter input danCOLLATE
klausa tidak valid dalam konteks itu (itulah sebabnyaNCHAR()
hanya mendukung Karakter Tambahan ketika database saat ini memiliki susunan default yang Sadar Karakter-Sadar; tetapi ini tidak perlu ketidaknyamanan yang dapat diubah, jadi silakan pilih saran saya:Fungsi NCHAR () harus selalu mengembalikan Karakter Tambahan untuk nilai 0x10000 - 0x10FFFF terlepas dari susunan default basis data aktif ).Bagaimana SQL Server dapat menyimpan dan mengambil karakter tambahan tanpa kehilangan data dijelaskan di bagian atas jawaban ini. Tetapi, tidak benar bahwa
NCHAR
satu-satunya fungsi bawaan yang memiliki masalah dengan Karakter Tambahan (saat tidak menggunakan SCA Collation). Misalnya,LEN(N'😀' COLLATE SQL_Latin1_General_CP1_CI_AS)
mengembalikan nilai 2 sementaraLEN(N'😀' COLLATE Latin1_General_100_CI_AS_SC)
mengembalikan nilai 1.Jika Anda pergi ke tautan kedua yang diposting di Pertanyaan (yaitu "Informasi Pengumpulan Karakter Tambahan Microsoft") dan gulirkan sedikit ke bawah, Anda akan melihat bagan fungsi bawaan dan bagaimana mereka berperilaku berdasarkan Kolasi efektif.
Dalam versi SQL Server sebelum 2012 Anda tidak bisa. Tetapi, dimulai dengan SQL Server 2012, Anda dapat menggunakan kueri berikut:
Permintaan Anda sudah dekat, tetapi pola dimulai dengan
SQL
dan SQL Server Collations (yaitu yang dimulai denganSQL_
) telah ditinggalkan untuk sementara waktu karena Windows Collations (yang tidak dimulai denganSQL_
). Jadi,SQL_
Collations tidak diperbarui dan karenanya tidak memiliki versi yang lebih baru yang akan menyertakan_SC
opsi (dan mulai di SQL Server 2017, semua collations baru secara otomatis mendukung Karakter Tambahan dan tidak perlu, atau memiliki,_SC
bendera; dan ya, kueri ditampilkan segera di atas akun untuk itu serta mengambil_UTF8
collations yang ditambahkan di SQL Server 2019).Tidak, Anda tidak dapat menginstal Collations ke versi SQL Server sebelumnya.
Saat tidak menggunakan Collation SCA, Anda bisa menyuntikkan Poin Kode di atas 65535 / U + FFFF dengan dua cara:
NCHAR()
fungsi, masing-masing dengan satu bagian dari pasanganVARBINARY
bentuk urutan byte Little Endian (yaitu dibalik).Dua metode ini memasukkan Karakter Tambahan / Pasangan Pengganti akan bekerja bahkan jika Kolasi yang efektif adalah Karakter Tambahan-Sadar, dan harus bekerja sama di semua versi SQL Server, setidaknya sejauh 2005 (walaupun mungkin juga akan bekerja di SQL Server 2000 juga).
Contoh:
💩
MEMPERBARUI
Anda dapat menggunakan iTVF berikut untuk mendapatkan nilai Pasangan Pengganti (dalam keduanya
INT
dan dalamBINARY
bentuk) dari Titik Kode mana saja antara 65536 - 1114111 (0x010000 - 0x10FFFF). Dan, sementara parameter input bertipeINT
, Anda bisa meneruskan dalam bentuk biner / hex dari Kode Point dan secara implisit akan dikonversi ke nilai integer yang benar.Menggunakan fungsi di atas, dua pertanyaan berikut:
keduanya mengembalikan yang berikut:
UPDATE 2: Pembaruan Yang Lebih Baik!
Saya telah mengadaptasi iTVF yang ditunjukkan di atas untuk sekarang mengembalikan 188.657 poin kode sehingga Anda tidak perlu mencocokkannya dengan nilai tertentu. Tentu saja, sebagai TVF, Anda dapat menambahkan
WHERE
klausa untuk memfilter pada titik kode tertentu, atau rentang titik kode, atau "karakter serupa", dll. Dan, itu termasuk kolom tambahan dengan urutan pelarian yang telah diformat untuk membangun setiap kode point (baik BMP dan Karakter Tambahan) dalam T-SQL, HTML, dan C-style (yaitu\xHHHH
). Baca semua tentang ini di sini:Tip SSMS # 3: Mudah Mengakses / Meneliti SEMUA Karakter Unicode (Ya, Termasuk Emoji 😸)
sumber