Perché dobbiamo mettere N prima delle stringhe in Microsoft SQL Server?


34

Sto imparando T-SQL. Dagli esempi che ho visto, per inserire del testo in una varchar()cella, posso scrivere solo la stringa da inserire, ma per le nvarchar()celle, ogni esempio ha come prefisso le stringhe con la lettera N.

Ho provato la seguente query su una tabella che ha nvarchar()righe e funziona bene, quindi il prefisso N non è richiesto:

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

Perché le stringhe hanno il prefisso N in ogni esempio che ho visto?

Quali sono i pro o i contro dell'utilizzo di questo prefisso?


La N non è necessaria solo per le stringhe letterali?
Wayne In Yak,

Il polacco è una lingua non latina ????
Heckflosse_230,

2
Nsignifica Nazionale, come in "Carattere variabile nazionale", vedere Tipi di dati SQL ANSI equivalenti .
ErikE,

Sono d'accordo con questa domanda e nessuno ha ancora risposto, AFAICT. Forse potrebbe essere ribadito come “Perché è brutto lasciare SQL implicitamente convertire il mio VARCHARa NVARCHARquando il mio letterale stringa è ASCII?”.
binki,

Questa domanda è già stata posta e ha risposto qui: Qual è la differenza tra varchar e nvarchar?

Risposte:


27

NVarchar è utilizzato per Unicode. Se il database non memorizza dati multilingue, è possibile continuare a utilizzare Varchar. Ad esempio: N'abc'converte semplicemente la stringa in Unicode.


2
Perché allora non devi aggiungere il prefisso U anziché N?
Attila Kun,

U potrebbe essere confuso per non firmato come ipotesi
JB King

U&'abc'è il modo giusto per specificare le stringhe Unicode. Vedi SQL 2003 BNF
ceving

2
La N sta effettivamente per set di "Caratteri di lingua nazionale".
Mike Bovenlander,

23

Per impostazione predefinita, SQL Server utilizza i codici di carattere di Windows 1252 per varchar . Contiene la maggior parte dei caratteri per le lingue latine (inglese, tedesco, francese, ecc.) Ma non contiene caratteri per le lingue non latine (polacco, russo, ecc.). Come affermato da @Pieter B, nvarchar è usato per aggirare quel problema perché è per Unicode che contiene quei caratteri mancanti. Questo ha un costo, ci vuole il doppio dello spazio per immagazzinare nvarchar rispetto a varchar.

Mettere N davanti alla stringa assicura che i caratteri vengano convertiti in Unicode prima di essere inseriti in una colonna nvarchar. La maggior parte delle volte starai bene lasciando N spento, ma non lo consiglierei. È molto meglio prevenire che curare.


3
Solo un chiarimento: il server SQL "per impostazione predefinita" utilizza la codifica corrispondente alle regole di confronto del campo Varchar, che è sostituibile al momento della creazione del campo, in genere sulla base delle regole di confronto predefinite per l'istanza. Le regole di confronto predefinite per l'istanza possono essere impostate al momento dell'installazione, ma generalmente corrispondono al CP_ACP delle impostazioni internazionali predefinite del sistema. Sarà Windows 1252 su una macchina inglese-americana, ma 932 su una macchina con un sistema giapponese locale, 1251 su una macchina russa, ecc. La morale della storia? Usa NVarchar :)
JasonTrue il

1
Finora questa è l'unica risposta che risponde alla domanda posta "Perché usare il prefisso N su stringhe letterali poiché SQL transcodificherà implicitamente?". Le altre risposte sono tutte per una domanda diversa "Qual è la differenza tra nvarchar e varchar?"
Timbo,

18

Perché MS SQL Server ha uno scarso supporto per UTF-8 rispetto ad altri RDBMS.

MS SQL Server segue la convenzione, utilizzata all'interno di Windows, che le stringhe "strette" ( charin C ++ CHARo VARCHARin SQL) sono codificate in una "code page" legacy. Il problema con le code page è che hanno un numero limitato di caratteri (la maggior parte sono codifiche a byte singolo, che limita il reportoire a 256 caratteri) e sono progettate attorno a una singola lingua (o gruppo di lingue con alfabeti simili). Ciò rende difficile l'archiviazione di dati multilingue. Ad esempio, non è possibile archiviare dati sia russi che ebraici perché il russo utilizza la code page 1251 e l'ebraico utilizza la code page 1255 .

Unicode risolve questo problema utilizzando un singolo set di caratteri in codice gigante con spazio per oltre un milione di caratteri, abbastanza per rappresentare ogni lingua del mondo. Esistono diversi schemi di codifica Unicode; Microsoft preferisce utilizzare UTF-16 , per motivi storici . Poiché UTF-16 rappresenta le stringhe come una sequenza di unità di codice a 16 bit anziché i tradizionali 8 bit, è necessario un tipo di carattere separato. In MSVC ++, questo è wchar_t. E in MS SQL, è NCHARo NVARCHAR. È l' Nacronimo di "nazionale" , il che mi sembra arretrato perché Unicode riguarda l' internazionalizzazione, ma questa è la terminologia ISO.

Altre implementazioni SQL consentono di archiviare il testo UTF-8 in una VARCHARcolonna. UTF-8 è una codifica a lunghezza variabile (1-4 byte per carattere) ottimizzata per il caso in cui i dati si trovano principalmente nell'intervallo latino di base (che sono rappresentati con lo stesso 1 byte per carattere di ASCII), ma possono rappresentare qualsiasi carattere Unicode. Pertanto, eviteresti il ​​problema del doppio dello spazio menzionato da bwalk2895.

Sfortunatamente, MS SQL Server non supporta UTF-8VARCHAR , quindi invece devi utilizzare UTF-16 (e sprecare spazio per il testo ASCII), utilizzare una tabella codici non Unicode (e perdere la capacità di rappresentare caratteri stranieri), o memorizzare UTF-8 in una BINARYcolonna (e gestire inconvenienti come le funzioni della stringa SQL che non funzionano correttamente o che devono visualizzare i dati come dump esadecimale nel proprio gestore DB GUI).


1
Nelle versioni precedenti a SQL Server 2012, eseguono l'archiviazione utilizzando la codifica UCS-2, che è rigorosamente a 2 byte. Nelle versioni più recenti, usano UTF-16 che è una mappatura a lunghezza variabile a 4 byte per carattere (simile a UTF-8 ma a partire da 2 byte).
j123b567,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.