Tudo, eu tenho uma grande consulta SQL dinâmica (inevitável). Devido ao número de campos nos critérios de seleção, a string que contém o SQL dinâmico está crescendo mais de 4.000 caracteres. Agora, eu entendo que há um máximo de 4000 definido para NVARCHAR(MAX)
, mas olhando para o SQL executado no Server Profiler para a instrução
DELARE @SQL NVARCHAR(MAX);
SET @SQL = 'SomeMassiveString > 4000 chars...';
EXEC(@SQL);
GO
Parece funcionar (!?), para outra consulta que também é grande ela lança um erro que está associado a esse limite de 4000 (!?), basicamente corta todo o SQL após esse limite de 4000 e me deixa com um erro de sintaxe. Apesar disso, no criador de perfil, ele está mostrando essa consulta SQL dinâmica por completo (!?).
O que exatamente está acontecendo aqui e devo apenas converter esta variável @SQL para VARCHAR e continuar com isso?
Obrigado pelo seu tempo.
Ps. Também seria bom poder imprimir mais de 4.000 caracteres para olhar essas grandes consultas. Os seguintes são limitados a 4000
SELECT CONVERT(XML, @SQL);
PRINT(@SQL);
existe alguma outra maneira legal?
fonte
Respostas:
Seu entendimento está errado.
nvarchar(max)
pode armazenar até (e às vezes além) 2 GB de dados (1 bilhão de caracteres de byte duplo).De nchar e nvarchar em Livros online, a gramática é
O
|
personagem significa que essas são alternativas. ou seja, você especifica umn
ou o literalmax
.Se você optar por especificar um específico
n
, ele deve estar entre 1 e 4.000, mas o uso omax
define como um tipo de dados de objeto grande (substituição para ontext
qual está obsoleto).Na verdade, no SQL Server 2008, parece que para uma variável o limite de 2 GB pode ser excedido indefinidamente, sujeito a espaço suficiente em
tempdb
( mostrado aqui )Em relação às outras partes da sua pergunta
O truncamento durante a concatenação depende do tipo de dados.
varchar(n) + varchar(n)
irá truncar em 8.000 caracteres.nvarchar(n) + nvarchar(n)
irá truncar em 4.000 caracteres.varchar(n) + nvarchar(n)
irá truncar em 4.000 caracteres.nvarchar
tem maior precedência, então o resultado énvarchar(4,000)
[n]varchar(max)
+[n]varchar(max)
não truncará (para <2 GB).varchar(max)
+varchar(n)
não truncará (para <2 GB) e o resultado será digitado comovarchar(max)
.varchar(max)
+nvarchar(n)
não truncará (para <2 GB) e o resultado será digitado comonvarchar(max)
.nvarchar(max)
+varchar(n)
primeiro converterá avarchar(n)
entrada paranvarchar(n)
e, em seguida, fará a concatenação. Se o comprimento davarchar(n)
string for maior que 4.000 caracteres, a conversão será paranvarchar(4000)
e ocorrerá truncamento .Tipos de dados de literais de string
Se você usar o
N
prefixo e a string tiver <= 4.000 caracteres, ela será digitada comonvarchar(n)
onden
é o comprimento da string. PortantoN'Foo'
, será tratado comonvarchar(3)
exemplo. Se a string tiver mais de 4.000 caracteres, ela será tratada comonvarchar(max)
Se você não usar o
N
prefixo e a string tiver <= 8.000 caracteres, ela será digitada comovarchar(n)
onden
é o comprimento da string. Se mais comovarchar(max)
Para ambos os itens acima, se o comprimento da string for zero,
n
será definido como 1.Elementos de sintaxe mais recentes.
1. A
CONCAT
função não ajuda aquiO código acima retorna 8000 para ambos os métodos de concatenação.
2. Tenha cuidado com
+=
Devoluções
Observe que
@A
encontrou truncamento.Como resolver o problema que você está enfrentando.
Você está obtendo truncamento porque está concatenando dois
max
tipos que não são de dados ou porque está concatenando umavarchar(4001 - 8000)
string com umanvarchar
string digitada (parnvarchar(max)
).Para evitar o segundo problema, simplesmente certifique-se de que todos os literais de string (ou pelo menos aqueles com comprimentos no intervalo 4001 - 8000) sejam precedidos por
N
.Para evitar o primeiro problema, altere a atribuição de
Para
de modo que um
NVARCHAR(MAX)
esteja envolvido na concatenação desde o início (como o resultado de cada concatenação também será,NVARCHAR(MAX)
isso se propagará)Evitando truncamento ao visualizar
Certifique-se de ter selecionado o modo "resultados para grade", então você pode usar
As opções de SSMS permitem que você defina uma duração ilimitada para os
XML
resultados. Oprocessing-instruction
bit evita problemas com personagens como<
aparecer como<
.fonte
nvarchar(4000)
longo do caminho. Se uma string literal tiver menos de 4.000 caracteres, ela será tratada comonvarchar(x)
. Concatenar com outronvarchar(x)
valor truncará em vez de aumentar paranvarchar(max)
DECLARE @SQL NVARCHAR(MAX) = ''; SET @SQL = @SQL +
modo que umNVARCHAR(MAX)
esteja envolvido na concatenação.N
prefixo que será tratado comonvarchar(max)
sem ele, ele será tratado como, emvarchar(n)
seguida, implicitamente convertidonvarchar(4000)
quando você concatenar para umnvarchar
Ok, então se mais tarde na linha o problema for que você tem uma consulta que é maior do que o tamanho permitido (o que pode acontecer se continuar crescendo), você terá que dividi-la em pedaços e executar os valores da string. Então, digamos que você tenha um procedimento armazenado como o seguinte:
fonte
Você deve usar texto nvarchar também. isso significa que você simplesmente tem que ter um "N" antes de sua corda enorme e é isso! nenhuma limitação mais
fonte
nvarchar(n)
onde n é o comprimento da string. Portanto, N'Foo 'será tratado comonvarchar(3)
exemplo. Se a string tiver mais de 4.000 caracteres, ela será tratada comonvarchar(max)
. Se você não usar o prefixo N e a string tiver <= 8.000 caracteres, ela será digitada comovarchar(n)
onde n é o comprimento da string. Se mais comovarchar(max)
. Para ambos osA resposta aceita me ajudou, mas eu tropecei ao fazer a concatenação de varchars envolvendo declarações de caso. Eu sei que a pergunta do OP não envolve instruções de caso, mas achei que seria útil postar aqui para outras pessoas como eu, que acabaram aqui enquanto lutavam para construir longas instruções SQL dinâmicas envolvendo instruções de caso.
Ao usar declarações de caso com concatenação de string, as regras mencionadas na resposta aceita se aplicam a cada seção da declaração de caso independentemente.
fonte
fonte