Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Dimensione massima di una variabile varchar(max).

Per quanto ne so, non esiste un limite massimo nel 2008.

In SQL Server 2005 il codice nella tua domanda non riesce nell'assegnazione al @GGMMsg variabile con

Tentativo di aumentare la LOB oltre la dimensione massima consentita di 2.147.483.647 byte.

il codice seguente non riesce con

REPLICA:la lunghezza del risultato supera il limite di lunghezza (2 GB) del tipo di destinazione grande.

Tuttavia, sembra che queste limitazioni siano state tranquillamente revocate. Nel 2008

DECLARE @y VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),92681); 

SET @y = REPLICATE(@y,92681);

SELECT LEN(@y) 

Resi

8589767761

L'ho eseguito sul mio computer desktop a 32 bit, quindi questa stringa da 8 GB supera di gran lunga la memoria indirizzabile

In esecuzione

select internal_objects_alloc_page_count
from sys.dm_db_task_space_usage
WHERE session_id = @@spid

Restituito

internal_objects_alloc_page_co 
------------------------------ 
2144456    

quindi presumo che tutto questo venga archiviato in LOB pagine in tempdb senza convalida sulla lunghezza. La crescita del conteggio delle pagine è stata tutta associata a SET @y = REPLICATE(@y,92681); dichiarazione. L'assegnazione iniziale della variabile a @y e il LEN il calcolo non l'ha aumentato.

Il motivo per menzionarlo è perché il numero di pagine è enormemente più di quanto mi aspettassi. Supponendo una pagina da 8 KB, questo funziona a 16,36 GB, che è ovviamente più o meno il doppio di quanto sembrerebbe necessario. Suppongo che ciò sia probabilmente dovuto all'inefficienza dell'operazione di concatenazione delle stringhe che richiede di copiare l'intera stringa enorme e aggiungere un pezzo alla fine piuttosto che essere in grado di aggiungere alla fine della stringa esistente. Purtroppo al momento il .WRITE il metodo non è supportato per le variabili varchar(max).

Aggiunta

Ho anche testato il comportamento concatenando nvarchar(max) + nvarchar(max) e nvarchar(max) + varchar(max) . Entrambi consentono di superare il limite di 2 GB. Il tentativo di memorizzare i risultati di questo in una tabella, tuttavia, fallisce con il messaggio di errore Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes. ancora. Lo script è riportato di seguito (l'esecuzione potrebbe richiedere molto tempo).

DECLARE @y1 VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),2147483647); 
SET @y1 = @y1 + @y1;
SELECT LEN(@y1), DATALENGTH(@y1)  /*4294967294, 4294967292*/


DECLARE @y2 NVARCHAR(MAX) = REPLICATE(CAST('X' AS NVARCHAR(MAX)),1073741823); 
SET @y2 = @y2 + @y2;
SELECT LEN(@y2), DATALENGTH(@y2)  /*2147483646, 4294967292*/


DECLARE @y3 NVARCHAR(MAX) = @y2 + @y1
SELECT LEN(@y3), DATALENGTH(@y3)   /*6442450940, 12884901880*/

/*This attempt fails*/
SELECT @y1 y1, @y2 y2, @y3 y3
INTO Test