Todo, tengo una consulta SQL dinámica grande (inevitable). Debido a la cantidad de campos en los criterios de selección, la cadena que contiene el SQL dinámico está creciendo a más de 4000 caracteres. Ahora, entiendo que hay un máximo de 4000 establecido para NVARCHAR(MAX)
, pero mirando el SQL ejecutado en Server Profiler para la declaración
DELARE @SQL NVARCHAR(MAX);
SET @SQL = 'SomeMassiveString > 4000 chars...';
EXEC(@SQL);
GO
Parece funcionar (!?), para otra consulta que también es grande arroja un error que está asociado con este límite 4000 (!?), básicamente recorta todo el SQL después de este límite 4000 y me deja con un error de sintaxis. A pesar de esto en el generador de perfiles, está mostrando esta consulta SQL dinámica en su totalidad (!?).
¿Qué está sucediendo exactamente aquí? ¿Debería convertir esta variable @SQL a VARCHAR y seguir adelante?
Gracias por tu tiempo.
PD. También sería bueno poder imprimir más de 4000 caracteres para ver estas grandes consultas. Los siguientes están limitados a 4000
SELECT CONVERT(XML, @SQL);
PRINT(@SQL);
¿Hay alguna otra forma genial?
fuente
Respuestas:
Tu comprensión está mal.
nvarchar(max)
puede almacenar hasta (y a veces más) 2 GB de datos (mil millones de caracteres de doble byte).De nchar y nvarchar en Libros en línea, la gramática es
El
|
personaje significa que estas son alternativas. es decir, se especifica ya sean
o lo literalmax
.Si elige especificar un tipo específico
n
, debe estar entre 1 y 4.000, pero el uso lomax
define como un tipo de datos de objeto grande (el reemplazontext
está obsoleto).De hecho, en SQL Server 2008 parece que para una variable, el límite de 2 GB se puede exceder indefinidamente sujeto a suficiente espacio en
tempdb
(se muestra aquí )Respecto a las otras partes de su pregunta
El truncamiento al concatenar depende del tipo de datos.
varchar(n) + varchar(n)
se truncará a los 8.000 caracteres.nvarchar(n) + nvarchar(n)
se truncará a 4.000 caracteres.varchar(n) + nvarchar(n)
se truncará a 4.000 caracteres.nvarchar
tiene mayor precedencia por lo que el resultado esnvarchar(4,000)
[n]varchar(max)
+[n]varchar(max)
no se truncará (para <2GB).varchar(max)
+varchar(n)
no se truncará (para <2GB) y el resultado se escribirá comovarchar(max)
.varchar(max)
+nvarchar(n)
no se truncará (para <2GB) y el resultado se escribirá comonvarchar(max)
.nvarchar(max)
+varchar(n)
primero convertirá lavarchar(n)
entradanvarchar(n)
ay luego hará la concatenación. Si la longitud de lavarchar(n)
cadena es superior a 4.000 caracteres, lanvarchar(4000)
conversión será ay se producirá el truncamiento .Tipos de datos de cadenas literales
Si usa el
N
prefijo y la cadena tiene <= 4.000 caracteres de longitud, se escribiránvarchar(n)
donden
es la longitud de la cadena. AsíN'Foo'
será tratado comonvarchar(3)
por ejemplo. Si la cadena tiene más de 4000 caracteres, se tratará comonvarchar(max)
Si no usa el
N
prefijo y la cadena tiene <= 8,000 caracteres de longitud, se escribirávarchar(n)
donden
es la longitud de la cadena. Si más largo comovarchar(max)
Para ambos de los anteriores, si la longitud de la cadena es cero,
n
se establece en 1.Elementos de sintaxis más nuevos.
1. La
CONCAT
función no ayuda aquíLo anterior devuelve 8000 para ambos métodos de concatenación.
2. Tenga cuidado con
+=
Devoluciones
Tenga en cuenta que
@A
encontró truncamiento.Cómo resolver el problema que está experimentando.
Obtiene truncamiento porque está concatenando dos
max
tipos que no son de datos juntos o porque está concatenando unavarchar(4001 - 8000)
cadena a unanvarchar
cadena escrita (parnvarchar(max)
).Para evitar el segundo problema, simplemente asegúrese de que todos los literales de cadena (o al menos aquellos con longitudes en el rango 4001 - 8000) estén precedidos por
N
.Para evitar el primer problema, cambie la asignación de
A
de modo que an
NVARCHAR(MAX)
esté involucrado en la concatenación desde el principio (como resultado de cada concatenación también será,NVARCHAR(MAX)
esto se propagará)Evitar el truncamiento durante la visualización
Asegúrese de tener seleccionado el modo "resultados a la cuadrícula", luego puede usar
Las opciones de SSMS le permiten establecer una duración ilimitada para los
XML
resultados. Elprocessing-instruction
bit evita problemas con personajes como<
aparecer como<
.fuente
nvarchar(4000)
el camino. Si un literal de cadena tiene menos de 4000 caracteres, se trata comonvarchar(x)
. La concatenación de otronvarchar(x)
valor se truncará en lugar de ascender anvarchar(max)
DECLARE @SQL NVARCHAR(MAX) = ''; SET @SQL = @SQL +
para que anNVARCHAR(MAX)
esté involucrado en la concatenación.N
prefijo que se tratará comonvarchar(max)
sin él, se tratará como sivarchar(n)
se lanzara implícitamente anvarchar(4000)
cuando se concatene a unnvarchar
Bien, si más adelante en la línea el problema es que tiene una consulta que es mayor que el tamaño permitido (lo que puede suceder si sigue creciendo), tendrá que dividirla en trozos y ejecutar los valores de cadena. Entonces, digamos que tiene un procedimiento almacenado como el siguiente:
fuente
También debes usar texto nvarchar. eso significa que simplemente tienes que tener una "N" antes de tu cuerda masiva y ¡eso es todo! ya no hay limitación
fuente
nvarchar(n)
donde n es la longitud de la cadena. Entonces N'Foo 'será tratado comonvarchar(3)
por ejemplo. Si la cadena tiene más de 4.000 caracteres, se tratará comonvarchar(max)
. Si no usa el prefijo N y la cadena tiene <= 8,000 caracteres, se escribirá comovarchar(n)
donde n es la longitud de la cadena. Si más largo comovarchar(max)
. Para ambos de los anteriores, si la longitud de la cadena es cero, entonces n se establece en 1.La respuesta aceptada me ayudó, pero me tropecé mientras hacía la concatenación de varchars que involucraban declaraciones de casos. Sé que la pregunta del OP no implica declaraciones de casos, pero pensé que sería útil publicar esto aquí para otros como yo, que terminaron aquí mientras luchaban por construir declaraciones SQL dinámicas largas que involucren declaraciones de casos.
Cuando se utilizan declaraciones de casos con concatenación de cadenas, las reglas mencionadas en la respuesta aceptada se aplican a cada sección de la declaración de casos de forma independiente.
fuente
fuente