Saya punya meja dengan kolom varchar. Ini memungkinkan Merek Dagang (™), hak cipta (©) dan karakter Unicode lainnya seperti yang ditunjukkan di bawah ini.
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
Tetapi definisi varchar mengatakan, ini memungkinkan data string non-unicode. Tetapi simbol-simbol Merek Dagang (™) dan Terdaftar (®) adalah karakter Unicode . Apakah definisi tersebut bertentangan dengan properti dari tipe data varchar? Saya membaca beberapa tautan seperti yang pertama dan yang kedua . Tapi tetap saya tidak bisa mengerti mengapa itu memungkinkan string unicode ketika definisi mengatakan bahwa itu hanya memungkinkan nilai-nilai string non-unicode.
Jawaban:
Anda salah di sini. String Anda hanya berisi
ascii
karakter.Berikut ini adalah tes sederhana yang menunjukkan kepada Anda bahwa karakter Anda semuanya ascii (+ beberapa
extended ascii
dengan kode ascii antara 128 dan 255):Di sini Anda dapat dengan jelas melihat bahwa semua karakter Anda dikodekan 1-byte:
Ya mereka bukan karakter ascii murni tetapi mereka Extended ASCII .
Di sini saya menunjukkan kepada Anda karakter unicode yang nyata
Trademark(™)
beserta kode dan representasi binernya:Akhirnya, Anda dapat melihat bahwa
Trademark(™)
karakter unicode memiliki 8482 kode dan bukan 153:sumber
Ö
) dan dalam ISO-8859-1 (kadang-kadang disebut Latin1) itu adalah kode kontrol tanpa representasi yang dapat dicetak. Kecuali Anda tahu Anda akan selalu menggunakan codepage yang sama, lebih aman untuk tetap menggunakan karakter ANSI (127 atau kurang) atau menggunakan tipe Unicode. Codepage 1252 paling umum di SQL Server tetapi jauh dari mana-mana.Dari komentar, saya setuju "Extended ASCII" adalah istilah yang benar-benar buruk yang sebenarnya berarti halaman kode yang memetakan karakter / titik kode dalam kisaran 128-255, di luar rentang titik kode 0-127 standar yang ditentukan oleh ASCII.
SQL Server mendukung banyak halaman kode melalui collations. Karakter non-ASCII dapat disimpan dalam varchar selama susunan yang mendasarinya mendukung karakter tersebut.
Karakter '™' dapat disimpan dalam kolom varchar / char ketika halaman kode SQL Server 1250 atau lebih besar. Kueri di bawah ini akan mencantumkan ini:
Tetapi hanya sebagian dari ini yang juga mendukung karakter '©' sehingga susunan kolom perlu menjadi salah satu dari yang berikut untuk mendukung keduanya:
sumber
Sementara jawaban lain tidak salah, saya pikir akan membantu untuk menunjukkan kebingungan dalam terminologi dasar. Saya telah menekankan dua kata dalam kutipan di atas dari pertanyaan sebagai contoh dari kebingungan ini. Ketika dokumentasi SQL Server berbicara tentang Unicode dan non-Unicode Data , mereka tidak berbicara tentang karakter . Mereka berbicara tentang urutan byte yang mewakili karakter tertentu. Perbedaan utama antara jenis Unicode (
NCHAR
,NVARCHAR
,XML
, dan usang / jahatNTEXT
) dan jenis non-Unicode (CHAR
,VARCHAR
, dan usang / jahatTEXT
) adalah apa jenis urutan byte mereka dapat menyimpan.Jenis non-Unicode menyimpan salah satu dari beberapa pengkodean 8-bit, sedangkan jenis Unicode menyimpan pengodean Unicode 16-bit tunggal: UTF-16 Little Endian. Seperti jawaban lain yang disebutkan, karakter mana yang dapat disimpan dalam pengkodean 8-bit / non-Unicode tergantung pada halaman kode, yang ditentukan oleh Collation. Sementara yang lain telah mencatat bahwa nilai byte dari "karakter" dapat bervariasi di seluruh halaman kode yang ditemukan, nilai byte bahkan dapat bervariasi dalam halaman kode yang sama ketika berhadapan dengan salah satu dari beberapa halaman kode EBCDIC (variasi Windows- 1252), yang hanya ditemukan di SQL Server Collations yang lebih lama, yang seharusnya tidak benar-benar digunakan (yaitu yang memiliki nama yang dimulai dengan
SQL_
).Oleh karena itu, definisi tersebut akurat: karakter apa pun yang dapat Anda kelola untuk disimpan dalam tipe non-Unicode selalu 8-bit (bahkan jika mereka menggunakan dua nilai 8-bit dalam kombinasi sebagai "karakter" tunggal, yang merupakan apa yang Double- Halaman Byte Character Set / DBCS memungkinkan untuk). Dan tipe data Unicode selalu 16-bit, bahkan jika mereka kadang-kadang menggunakan dua nilai 16-bit dalam kombinasi sebagai "karakter" tunggal (yaitu pasangan pengganti yang pada gilirannya mewakili Karakter Tambahan).
DAN, karena SQL Server secara native mendukung pengkodean UTF-8 untuk
VARCHAR
danCHAR
tipe data pada SQL Server 2019,VARCHAR
tidak dapat lagi disebut sebagai "non-Unicode". Jadi, dimulai dengan beta publik pertama dari SQL Server 2019 pada September 2018, kita harus merujukVARCHAR
sebagai "datatype 8-bit", bahkan ketika berbicara dalam hal versi sebelum SQL Server 2019. Terminologi ini berlaku untuk semua 4 jenis pengkodean yang dapat digunakan denganVARCHAR
:Hanya
TEXT
tipe data (tidak digunakan pada SQL Server 2005, jadi jangan gunakan) adalah "non-Unicode", tapi itu hanya teknis, dan menyebutnya sebagai "8-bit datatype" yang akurat.NVARCHAR
,,NCHAR
danNTEXT
dapat disebut sebagai "UTF-16" atau "tipe data 16-bit". Oracle, saya percaya, menggunakan terminologi "Unicode-only" untukNVARCHAR
, tetapi itu tidak dengan jelas mengesampingkan kemungkinan menggunakan UTF-8 (juga enkode Unicode), yang tidak akan berfungsi, jadi mungkin yang terbaik untuk tetap menggunakan dua opsi pertama.Untuk detail tentang pengkodean UTF-8 baru, silakan lihat posting saya:
Dukungan UTF-8 Asli di SQL Server 2019: Juruselamat atau Nabi Palsu?
PS Saya perlahan-lahan bekerja dengan cara saya memperbarui dokumentasi SQL Server untuk mencerminkan perubahan ini.
PPS Microsoft telah memperbarui beberapa halaman dengan info UTF-8, termasuk dokumentasi char dan varchar yang dirujuk dalam pertanyaan. Itu tidak lagi mengandung frasa "non-Unicode". Tapi itu hanya FYI; itu tidak mengubah pertanyaan karena ini adalah tentang pengkodean non-Unicode yang mengandung karakter yang keliru dianggap hanya Unicode.
sumber
Pertanyaannya berisi kesalahpahaman sentral tentang apa itu Unicode. Set karakter Unicode, bersama dengan penyandiannya seperti UTF-8 dan UTF-16, adalah salah satu dari banyak cara untuk merepresentasikan teks dalam komputer, dan yang tujuannya adalah untuk menggantikan semua set dan penyandian karakter lainnya. Jika "data non-Unicode" berarti "karakter yang tidak ada dalam Unicode", maka tidak ada teks yang saya gunakan dalam jawaban ini yang dapat disimpan dalam jenis itu, karena semua huruf dalam alfabet Latin dan tanda baca umum yang digunakan dalam bahasa Inggris sehari-hari adalah termasuk dalam Unicode.
Representasi teks secara luas dapat dipikirkan dalam dua bagian: satu set karakter memetakan karakter yang berbeda (huruf, angka, simbol, dll) ke angka pada grafik referensi; dan pengkodean yang mewakili angka-angka tersebut sebagai pola bit (pada disk, melalui koneksi jaringan, dll). Di sini kita sebagian besar memusatkan perhatian pada bagian pertama: karakter mana yang terdaftar pada bagan untuk rangkaian karakter tertentu.
Karena Unicode bertujuan untuk memiliki angka (yang disebut "titik kode") untuk setiap karakter di dunia, referensi seperti Wikipedia akan sering merujuk pada posisi Unicode karakter sebagai informasi referensi standar. Namun, itu tidak berarti bahwa rangkaian karakter lain tidak juga memiliki pemetaan untuk karakter yang sama.
Salah satu set karakter tertua dan paling sederhana (dan penyandian) yang masih digunakan adalah ASCII, yang memiliki pemetaan untuk 128 karakter berbeda (0 hingga 127), karena menggunakan 7 bit untuk mengkodekan setiap karakter. Karena ini tidak termasuk banyak karakter beraksen dan simbol umum, pengkodean selanjutnya menggunakan 8 bit, dan memetakan 128 karakter pertama yang sama, menambah set karakter dengan mengisi posisi 128 hingga 255. Yang paling penting di antaranya adalah standar ISO 8859-1 dan ISO 8859- 15 , dan Kode Windows spesifik Microsoft .
Jadi, untuk kembali ke MS SQL Server: a "Unicode string", sebagai disimpan dalam
nchar
,nvarchar
atauntext
kolom, dapat mewakili semua karakter dipetakan dalam set karakter Unicode, karena menggunakan Unicode encoding untuk menyimpan data. Sebuah "non-Unicode string", yang disimpan dalamchar
,varchar
atautext
kolom, dapat hanya mewakili karakter dipetakan dalam beberapa pengkodean lainnya . Apa pun yang dapat Anda simpan di kolom non-Unicode juga dapat disimpan dalam kolom Unicode, tetapi tidak sebaliknya.Untuk mengetahui persis karakter mana yang dapat Anda simpan, Anda perlu mengetahui "susunan" yang digunakan, yang menentukan apa yang disebut Microsoft sebagai "halaman kode", seperti yang dijelaskan pada halaman referensi Microsoft ini . Mungkin dalam kasus Anda bahwa Anda menggunakan Kode yang sangat umum, yang saya sebutkan sebelumnya.
Karakter yang Anda sebutkan ada di Unicode dan Code Page 1252:
sumber