2011-09-12 45 views
7
DECLARE @str VARCHAR (MAX); 

SELECT @str = COALESCE(@str + CHAR(10), '') + 
     'EXECUTE CreateDeno ' + CAST(ID AS VARCHAR) 
FROM GL_To_Batch_Details 
WHERE TYPE = 'C' AND 
     Deno_ID IS NULL; 

--PRINT @str;--SELECT @str; 
**EXEC(@str);** 

editadoT-SQL VARCHAR (MAX) truncado

¿Se EXECUTE instrucción TRUNCATE cuerdas a 8.000 caracteres como PRINT? ¿Cómo puedo ejecutar una declaración SQL dinámica que tenga más de 8,000 caracteres?

Cualquier sugerencia sería calurosamente apreciada.

+3

creo que está confundido, no se puede 'PRINT' más de 8000 caracteres, que no quiere decir que @str está siendo truncada – Lamak

+0

He editado la cuestión de ser más específico sobre el problema. En realidad, cuando EXECUTE produjo el error, utilicé PRINT para ver qué se generó el T-SQL dinámico. En ambos casos, los valores de nvarchar (MAX) se han truncado. ¿Algunas ideas? –

Respuesta

12

PRINT tiene un límite de 8k en la salida.

También hay un límite de 8k en el panel de resultados de SSMS.

Ir a

Herramientas -> Opciones -> resultados de la consulta

para ver las opciones.

Para comprobar la longitud de los datos reales, marque:

SELECT LEN(@str)

+0

Bien. PRINT se utiliza aquí en lugar de EXEC para ver cuál es el problema real. –

+0

@Nick Bennet: [MSDN dice] (http://msdn.microsoft.com/en-us/library/ms188332 (v = SQL.90) .aspx): en versiones anteriores de SQL Server, las cadenas de caracteres están limitadas a 8,000 bytes. Esto requiere concatenar cadenas grandes para la ejecución dinámica. En SQL Server 2005, se pueden especificar los tipos de datos varchar (max) y nvarchar (max) que permiten cadenas de caracteres de hasta 2 gigabytes de datos. – Andomar

+0

Tuve que usar el tipo de datos NVARCHAR (MAX) junto con sp_executesql para que funcione. ¿Podría confirmar que se puede lograr lo mismo sin usar sp_executesql? Gracias. –

2

El default length de un varchar es de 30 caracteres:

CAST (ID AS VARCHAR) 

¿Es posible que id es más de 30 caracteres?

+0

No, no es posible que la ID tenga más de 30 caracteres. –

+1

Es una buena práctica que nunca use la longitud predeterminada, hay otros momentos en los que el valor predeterminado es 1. – HLGEM

2

El comando PRINT está ciertamente limitado a 8000 caracteres, independientemente de la longitud de la salida (o si es varchar (max)). Para evitar esto es necesario para emitir la cadena en trozos de <8000 caracteres


Actualizar: En respuesta a su edición, ejecutivo no limita la longitud de la cadena. He creado el siguiente ejemplo para demostrar esto:

DECLARE @str VARCHAR (MAX); 


;WITH CTE_Count AS 
(
    select counter = 1 
    union all 
    select counter = counter+1 
    from CTE_Count 
    Where counter < 2000 

) 
SELECT    
    @str=COALESCE(@str + CHAR (10) , 
     '') + 'select value=' + CAST (counter AS VARCHAR) 
from 
    CTE_Count 

Option (MAXRECURSION 0) 

PRINT len(@str);--SELECT @str; 

exec (@str) 

La ejecución de este imprime la longitud que 34892 caracteres, y todos los 2000 ejecutar sentencias se ejecutan (se advirtió, puede tardar unos minutos!)

0

Sucede al concatenar los literales si uno no es un varchar (max) el resultado enfermedad sea "implícita fundido" a varchar (8000).

Para generar un varchar literal (max) todas las partes deben ser varchar (max). Nota: Me sucedió a mí hacer actualizaciones en columnas varchar (max), nunca probadas con el comando EXEC.

También como se indicó en respuestas anteriores, el comando de impresión tiene un límite pero puede intentar seleccionar esa variable en lugar de imprimirla. (También allí es un límite en ese selecto longitud puede configurar en MS-SMS)

1

Al concatenar cadenas y el resultado es de tipo VARCHAR (MAX) y tiene más de 8000 caracteres, al menos un parámetro y/o el elemento el uso en la concatenación debe ser del tipo VARCHAR (MAX), de lo contrario el truncamiento ocurrirá en la cadena resultante y no será ejecutable en una instrucción EXEC.

Ejemplo:

DECLARE @sql AS VARCHAR(MAX); 
/* DECLARE @someItem AS VARCHAR(100); -- WILL CAUSE TRUNCATION WHEN @sql HAS LEN > 8000 */ 
DECLARE @someItem AS VARCHAR(MAX); -- All string variables need to be VARCHAR(MAX) when concatenating to another VARCHAR(MAX) 

SET @someItem = 'Just assume the resulting @sql variable goes over 8000 characters...'; 
SET @sql = 'SELECT Something FROM Somewhere WHERE SomeField = ''' + @someItem + ''''; 

EXEC (@sql); 
--PRINT @sql; 

Más información sobre MSDN.

"Si el resultado de la concatenación de cadenas supera el límite de 8000 bytes, el resultado se trunca. Sin embargo, si al menos uno de los cadenas concatenadas es un gran tipo de valor, el truncamiento no lo hace ocurrir "

0

También quería ver lo que estaba enviando a Exec, y me confundí con el límite de IMPRESIÓN. Tuve que escribir un proceso para imprimir en trozos.

CREATE PROCEDURE [dbo].[KFX_PrintVarcharMax] 
    @strMax varchar(max) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE 
     @index int = 0, 
     @start int = 1, 
     @blkSize int = 2000; 


    WHILE @Start < LEN(@strMax) 
    BEGIN 
     IF @start + @blkSize >= LEN(@strMax) 
     BEGIN 
      -- If remainder is less than blocksize print the remainder, and exit. 
      PRINT SUBSTRING(@strMax, @start, @blkSize) 
      BREAK; 
     END 
     -- Else find the next terminator (beyond the blksize) 
     SET @index = CHARINDEX(CHAR(10), @strMax, @start + @blkSize); 
     if @index >= @start 
     BEGIN 
      PRINT SubString(@strMax, @start, @index - @start + 1) 
      SET @start = @index + 1; 
      SET @blkSize = CASE WHEN @start + 2000 < LEN(@strMax) THEN 2000 
          ELSE LEN(@strMax) - @start + 1 END 
     END 
     ELSE 
     BEGIN 
      -- No char(10) found. Just print the rest. 
      PRINT SUBSTRING(@strMax, @start, LEN(@strMax)) 
      BREAK; 
     END 
    END 

END 
Cuestiones relacionadas