Mengapa kita harus meletakkan N sebelum string di Microsoft SQL Server?

34

Saya sedang belajar T-SQL. Dari contoh yang saya lihat, untuk memasukkan teks ke dalam varchar()sel, saya dapat menulis hanya string yang akan disisipkan, tetapi untuk nvarchar()sel, setiap contoh awalan string dengan huruf N.

Saya mencoba kueri berikut pada tabel yang memiliki nvarchar()baris, dan berfungsi dengan baik, jadi awalan N tidak diperlukan:

insert into [TableName] values ('Hello', 'World')

Mengapa string diawali dengan N dalam setiap contoh yang saya lihat?

Apa pro atau kontra dari menggunakan awalan ini?

qinking126
sumber
Bukankah N hanya diperlukan untuk string literal?
Wayne In Yak
Bahasa Polandia adalah bahasa non-Latin ????
Heckflosse_230
2
Nberarti Nasional, seperti dalam "Karakter Memvariasikan Nasional", lihat Tipe Data SQL ANSI Setara .
ErikE
Saya setuju dengan pertanyaan ini dan tidak ada yang menjawab sejauh ini, AFAICT. Mungkin itu bisa dinyatakan kembali sebagai "mengapa buruk untuk membiarkan SQL secara implisit mengkonversi saya VARCHARke NVARCHARketika string literal saya adalah ASCII?".
binki
Pertanyaan ini sudah ditanyakan dan dijawab di sini: Apa perbedaan antara varchar dan nvarchar?

Jawaban:

27

NVarchar digunakan untuk Unicode. Jika database Anda tidak menyimpan data multibahasa, Anda dapat tetap menggunakan Varchar. Sebagai contoh: N'abc'cukup konversi string Anda ke unicode.

Pieter B
sumber
2
Mengapa Anda tidak harus awalan dengan U alih-alih N?
Attila Kun
Anda dapat dikelirukan karena tidak bertanda tangan sebagai dugaan
JB King
U&'abc'adalah cara yang tepat untuk menentukan string Unicode. Lihat SQL 2003 BNF
ceving
2
N sebenarnya adalah singkatan dari set "Karakter Bahasa Nasional".
Mike Bovenlander
23

Secara default SQL server menggunakan kode karakter Windows-1252 untuk varchar . Ini berisi sebagian besar karakter untuk bahasa berbasis latin (Inggris, Jerman, Perancis, dll.) Tetapi tidak mengandung karakter untuk bahasa berbasis non-latin (Polandia, Rusia, dll.). Seperti yang dinyatakan oleh @Pieter B, nvarchar digunakan untuk mengatasi masalah itu karena untuk Unicode yang berisi karakter-karakter yang hilang. Ini membutuhkan biaya, dibutuhkan dua kali lebih banyak ruang untuk menyimpan nvarchar daripada varchar.

Menempatkan N di depan string Anda memastikan karakter dikonversi ke Unicode sebelum ditempatkan ke dalam kolom nvarchar. Sebagian besar waktu Anda akan baik-baik saja meninggalkan N off, tetapi saya tidak akan merekomendasikan hal ini. Jauh lebih baik aman daripada menyesal.

bwalk2895
sumber
3
Hanya klarifikasi: "Secara default" SQL server menggunakan pengkodean yang sesuai dengan susunan bidang Varchar, yang dapat ditimpa pada saat pembuatan bidang, umumnya didasarkan pada susunan default untuk contoh Anda. Kolasi default untuk instance Anda dapat ditetapkan pada waktu instalasi, tetapi umumnya sesuai dengan CP_ACP lokal sistem default. Itu akan menjadi Windows 1252 pada mesin AS-Inggris, tetapi 932 pada mesin dengan sistem lokal Jepang, 1251 pada mesin Rusia, dll. Moral dari cerita ini? Gunakan NVarchar :)
JasonTrue
1
Sejauh ini ini adalah satu-satunya jawaban yang menjawab pertanyaan seperti yang diajukan "Mengapa menggunakan awalan N pada string literal karena SQL secara implisit akan transcode?". Jawaban lainnya adalah semua untuk pertanyaan yang berbeda, "Apa perbedaan antara nvarchar vs varchar?"
Timbo
18

Karena MS SQL Server memiliki dukungan yang buruk untuk UTF-8 dibandingkan dengan RDBMS lainnya.

MS SQL Server mengikuti konvensi, yang digunakan dalam Windows itu sendiri, bahwa string "sempit" ( chardalam C ++, CHARatau VARCHARdalam SQL) dikodekan dalam "halaman kode" lama. Masalah dengan halaman kode adalah bahwa mereka memiliki jumlah karakter yang terbatas (kebanyakan adalah pengkodean byte tunggal, yang membatasi reportoire menjadi 256 karakter) dan dirancang di sekitar satu bahasa (atau kelompok bahasa dengan huruf yang sama). Ini membuatnya sulit untuk menyimpan data multibahasa. Misalnya, Anda tidak dapat menyimpan data Rusia dan Ibrani karena Rusia menggunakan halaman kode 1251 dan bahasa Ibrani menggunakan kode halaman 1255 .

Unicode memecahkan masalah ini dengan menggunakan satu set karakter kode raksasa dengan ruang lebih dari satu juta karakter, cukup untuk mewakili setiap bahasa di dunia. Ada beberapa skema pengkodean Unicode; Microsoft lebih suka menggunakan UTF-16 , karena alasan historis . Karena UTF-16 mewakili string sebagai urutan unit kode 16-bit dan bukan 8-bit tradisional, diperlukan tipe karakter terpisah. Di MSVC ++, ini wchar_t. Dan dalam MS SQL, itu NCHARatau NVARCHAR. The Nsingkatan dari "nasional" , yang tampaknya belakang untuk saya karena Unicode adalah tentang antar -nationalization, tapi itu terminologi ISO.

Implementasi SQL lainnya memungkinkan Anda menyimpan teks UTF-8 dalam sebuah VARCHARkolom. UTF-8 adalah pengkodean variabel-panjang (1-4 byte per karakter) yang dioptimalkan untuk kasus ketika data Anda sebagian besar dalam kisaran Latin Dasar (yang direpresentasikan sebagai 1 byte yang sama per karakter seperti ASCII), tetapi dapat mewakili setiap karakter Unicode. Dengan demikian, Anda akan menghindari masalah "dua kali lebih banyak ruang" yang disebutkan oleh bwalk2895.

Sayangnya, MS SQL Server tidak mendukung UTF-8VARCHAR , jadi alih-alih Anda harus menggunakan UTF-16 sebagai gantinya (dan membuang ruang untuk teks ASCII), gunakan halaman kode non-Unicode (dan kehilangan kemampuan untuk mewakili karakter asing), atau menyimpan UTF-8 dalam BINARYkolom (dan menangani ketidaknyamanan seperti fungsi string SQL tidak berfungsi dengan baik, atau harus melihat data sebagai dump hex di manajer GUI DB Anda).

dan04
sumber
1
Dalam versi yang lebih awal dari SQL Server 2012, mereka menggunakan pengkodean UCS-2, yang hanya 2 byte. Dalam versi yang lebih baru, mereka menggunakan UTF-16 yang merupakan pemetaan panjang variabel hingga 4bytes per karakter (mirip dengan UTF-8 tetapi mulai dari 2 byte).
j123b567