Por que precisamos colocar N antes das strings no Microsoft SQL Server?


34

Estou aprendendo T-SQL. Dos exemplos que eu vi, para inserir texto em uma varchar()célula, eu posso escrever apenas a string a ser inserida, mas para nvarchar()células, todo exemplo prefixa as strings com a letra N.

Eu tentei a seguinte consulta em uma tabela que possui nvarchar()linhas e funciona bem, portanto o prefixo N não é necessário:

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

Por que as strings são prefixadas com N em todos os exemplos que eu já vi?

Quais são os prós ou contras do uso desse prefixo?


O N não é necessário apenas para cadeias literais?
Wayne In Yak

O polonês é um idioma não baseado em latim ????
Heckflosse_230

2
Nsignifica Nacional, como em "Caractere Variável Nacional", consulte Tipos de Dados SQL ANSI Equivalentes .
ErikE

Concordo com esta pergunta e ninguém a respondeu até agora, AFAICT. Talvez possa ser reapresentado como "por que é ruim permitir que o SQL converta implicitamente meu VARCHARpara NVARCHARquando minha string literal é ASCII?".
binki

Esta pergunta já foi feita e respondida aqui: Qual é a diferença entre varchar e nvarchar?

Respostas:


27

NVarchar é usado para Unicode. Se seu banco de dados não estiver armazenando dados multilíngues, você poderá continuar usando o Varchar. Como um exemplo: N'abc'simplesmente converte sua string em unicode.


2
Por que você não precisa prefixar U em vez de N?
Attila Kun

U poderia ser confundido para não assinado como um palpite
JB rei

U&'abc'é o caminho certo para especificar cadeias Unicode. Veja o SQL 2003 BNF
26/10/2015

2
ON significa realmente o conjunto "National Language Character".
precisa saber é o seguinte

23

Por padrão, o SQL server usa os códigos de caracteres do Windows-1252 para varchar . Ele contém a maioria dos caracteres para idiomas baseados em latim (inglês, alemão, francês etc.), mas não contém caracteres para idiomas baseados em latim (polonês, russo etc.). Conforme declarado pelo @Pieter B, o nvarchar é usado para contornar esse problema, pois é para Unicode que contém os caracteres ausentes. Isso tem um custo, é necessário o dobro do espaço para armazenar nvarchar que varchar.

Colocar N na frente da sequência garante que os caracteres sejam convertidos em Unicode antes de serem colocados em uma coluna nvarchar. Na maioria das vezes você fica bem deixando o N desligado, mas eu não o recomendaria. É muito melhor prevenir do que remediar.


3
Apenas um esclarecimento: O servidor SQL "Por padrão" usa a codificação correspondente ao agrupamento do campo Varchar, que é substituível no momento da criação do campo, geralmente com base no agrupamento padrão da sua instância. O agrupamento padrão para sua instância pode ser definido no momento da instalação, mas geralmente corresponde ao CP_ACP do código do idioma padrão do sistema. Isso será o Windows 1252 em uma máquina em inglês dos EUA, mas 932 em uma máquina com localidade de sistema japonesa, 1251 em uma máquina russa etc. A moral da história? Use NVarchar :)
JasonTrue 14/07

1
Até o momento, essa é a única resposta que aborda a pergunta, como "Por que usar o prefixo N em cadeias literais, pois o SQL transcodifica implicitamente?". As outras respostas são todas para uma pergunta diferente "Qual é a diferença entre nvarchar x varchar?"
Timbo 31/07

18

Porque o MS SQL Server tem um suporte ruim para o UTF-8 em comparação com outros RDBMS.

O MS SQL Server segue a convenção, usada no próprio Windows, de que seqüências de caracteres "estreitas" ( charem C ++ CHARou VARCHARSQL) são codificadas em uma "página de códigos" herdada. O problema com as páginas de código é que eles têm um número limitado de caracteres (a maioria é codificação de byte único, o que limita o porto a 256 caracteres) e são projetados em um único idioma (ou grupo de idiomas com alfabetos semelhantes). Isso dificulta o armazenamento de dados multilíngues. Por exemplo, você não pode armazenar dados em russo e hebraico porque o russo usa a página de códigos 1251 e o hebraico usa a página de códigos 1255 .

O Unicode resolve esse problema usando um único conjunto de caracteres codificados gigantes com espaço para mais de um milhão de caracteres, o suficiente para representar todos os idiomas do mundo. Existem vários esquemas de codificação Unicode; A Microsoft prefere usar UTF-16 , por razões históricas . Como o UTF-16 representa cadeias de caracteres como uma sequência de unidades de código de 16 bits em vez dos tradicionais de 8 bits, é necessário um tipo de caractere separado. No MSVC ++, é isso wchar_t. E no MS SQL, é NCHARou NVARCHAR. A Nexpressão "nacional" , que me parece inversa, porque o Unicode é sobre inter- nacionalização, mas essa é a terminologia ISO.

Outras implementações SQL permitem armazenar texto UTF-8 em uma VARCHARcoluna. UTF-8 é uma codificação de comprimento variável (1-4 bytes por caractere) otimizada para os casos em que seus dados estão principalmente no intervalo Latim básico (que são representados como o mesmo 1 byte por caractere que ASCII), mas podem representar qualquer caractere Unicode. Assim, você evitaria o problema "duas vezes mais espaço" mencionado por bwalk2895.

Infelizmente, o MS SQL Server não oferece suporte a UTF-8VARCHAR ; portanto, você deve usar UTF-16 (e desperdiçar espaço para texto ASCII), usar uma página de código que não seja Unicode (e perder a capacidade de representar caracteres estrangeiros), ou armazene UTF-8 em uma BINARYcoluna (e lide com inconvenientes, como as funções de cadeia de caracteres SQL que não estão funcionando corretamente ou com a exibição dos dados como um dump hexadecimal no gerenciador de banco de dados da GUI).


1
Nas versões anteriores ao SQL Server 2012, eles usam a codificação UCS-2, que é estritamente 2 bytes. Nas versões mais recentes, eles estão usando o UTF-16, que é o mapeamento de comprimento variável para 4 bytes por caractere (semelhante ao UTF-8, mas começando com 2 bytes).
J123b567
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.