Чому нам потрібно поставити N перед рядками в Microsoft SQL Server?


34

Я вивчаю T-SQL. З прикладів, які я бачив, щоб вставити текст у varchar()комірку, я можу написати лише рядок для вставки, але для nvarchar()комірок кожен приклад префіксує рядки буквою N.

Я спробував наступний запит на таблиці, у якій є nvarchar()рядки, і він працює чудово, тому префікс N не потрібен:

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

Чому рядки мають префікс N у кожному прикладі, який я бачив?

Які плюси чи мінуси використання цього префікса?


Хіба N не потрібен лише для буквальних рядків?
Wayne In Yak

Польська мова - це не латинська мова ????
Heckflosse_230

2
Nозначає Національний, як у "Національному різноманітному символі", див. Еквівалентні типи даних ANSI SQL .
ЕрікЕ

Я погоджуюся з цим питанням, і поки ніхто на нього не відповів, AFAICT. Може бути , це можна було б сформулювати так : «Чому це погано , щоб дозволити SQL неявно конвертувати мій VARCHARв NVARCHARколи моя рядок літерал ASCII?».
бінкі

Це питання вже було задано і тут відповіли: Яка різниця між варчаром і нварчаром?

Відповіді:


27

NVarchar використовується для Unicode. Якщо у вашій базі даних не зберігаються багатомовні дані, ви можете продовжувати використовувати Varchar. Як приклад: N'abc'просто перетворює рядок в unicode.


2
Чому тоді вам не доведеться префікс з U замість N?
Аттіла Кун

Ви могли б переплутати за непідписаний як здогад
JB King

U&'abc'це правильний спосіб вказати рядки Unicode. Дивіться BNF SQL 2003
закінчення

2
N насправді означає набір "Характер національної мови".
Майк Бовенлендер

23

За замовчуванням SQL-сервер використовує коди символів Windows-1252 для varchar . Він містить більшість символів для латинських мов (англійська, німецька, французька тощо), але він не містить символів для мов на основі не латинських мов (польська, російська тощо). Як зазначає @Pieter B, nvarchar використовується для подолання цієї проблеми, оскільки саме для Unicode містяться ці відсутні символи. Це коштує дорого, це потребує вдвічі більше місця для зберігання nvarchar, ніж варчар.

Якщо поставити N перед рядком, це гарантує перетворення символів у Unicode перед тим, як розмістити його у стовпчик nvarchar. Більшу частину часу вам буде добре, покинувши N, але я не рекомендував би його. Набагато краще бути безпечним, ніж шкодувати.


3
Лише уточнення: "За замовчуванням" SQL-сервер використовує кодування, відповідне порівнянню поля Varchar, яке можна перезаписати на момент створення поля, як правило, виходячи з порівняння за замовчуванням для вашого примірника. Порівняння за замовчуванням для вашого примірника може бути встановлено під час встановлення, але, як правило, відповідає CP_ACP локальної системи за замовчуванням. Це буде Windows 1252 на американсько-англійській машині, але 932 на машині з японською локальною системою, 1251 на російській машині тощо. Мораль історії? Використовуйте NVarchar :)
JasonTrue

1
Поки що це єдина відповідь, на яку звертається із запитанням "Навіщо використовувати префікс N у буквальних рядках, оскільки SQL буде неявно перекодувати?". Інші відповіді - на інше питання "Яка різниця між nvarchar проти varchar?"
Тімбо

18

Оскільки MS SQL Server має слабку підтримку UTF-8 порівняно з іншими RDBMS.

MS SQL Server дотримується домовленості, що використовується в самій Windows, що "вузькі" рядки ( charв C ++ CHARабо VARCHARв SQL) кодуються в застарілу "кодову сторінку". Проблема сторінок коду полягає в тому, що вони мають обмежену кількість символів (більшість - це однобайтові кодування, що обмежує репортаж на 256 символів) і розроблені навколо однієї мови (або групи мов з подібними алфавітами). Це ускладнює зберігання багатомовних даних. Наприклад, ви не можете зберігати і російські, і єврейські дані, оскільки російська використовує кодову сторінку 1251, а іврит використовує кодову сторінку 1255 .

Unicode вирішує цю проблему, використовуючи один гігантський набір закодованих символів, в якому розміщено більше мільйона символів, достатньо для представлення кожної мови у світі. Існує кілька схем кодування Unicode; Microsoft вважає за краще використовувати UTF-16 з історичних причин . Оскільки UTF-16 представляє рядки як послідовність 16-бітних одиниць коду замість традиційних 8-бітових, потрібен окремий тип символів. У MSVC ++ це так wchar_t. А в MS SQL це NCHARчи NVARCHAR. Поняття N"національне" , що мені здається назад, тому що Unicode - це питання про інтернаціоналізацію , але це термінологія ISO.

Інші реалізації SQL дозволяють зберігати текст UTF-8 у VARCHARстовпці. UTF-8 - кодування змінної довжини (1-4 байти на символ), яке оптимізоване для випадку, коли ваші дані здебільшого знаходяться в базовому діапазоні латинської ланки (які представлені тим самим 1 байтом на символ, що й ASCII), але можуть представляти будь-який символ Unicode. Таким чином, ви уникнете проблеми "вдвічі більше місця", згаданої bwalk2895.

На жаль, MS SQL Server не підтримує UTF-8VARCHAR , тому замість цього вам доведеться або замість цього використовувати UTF-16 (і витрачати простір для тексту ASCII), використовувати кодову сторінку, яка не використовується Unicode (і втрачати здатність представляти іноземні символи), або зберігати UTF-8 у BINARYстовпці (і вирішувати незручності, такі як функції струнних функцій SQL, які не працюють належним чином, або потребувати перегляду даних як шістнадцятковий дамп у вашому диспетчері даних GUI).


1
У версіях, раніше SQL Server 2012, вони зберігаються з використанням кодування UCS-2, що є строго 2-байтним. У новіших версіях вони використовують UTF-16, що відображає змінну довжину до 4 байт на символ (аналогічно UTF-8, але починаючи з 2 байт).
j123b567
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.