Pour autant que je sache, il n'y a pas de limite supérieure en 2008.
Dans SQL Server 2005, le code de votre question échoue lors de l'affectation de la @GGMMsg
variable avec
Tentative de croissance du LOB au-delà de la taille maximale autorisée de 2 147 483 647 octets.
le code ci-dessous échoue avec
RÉPLIQUER: La longueur du résultat dépasse la limite de longueur (2 Go) du type de grande taille cible.
Cependant, il semble que ces limitations aient été tranquillement levées. En 2008
DECLARE @y VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),92681);
SET @y = REPLICATE(@y,92681);
SELECT LEN(@y)
Retour
8589767761
J'ai exécuté ceci sur ma machine de bureau 32 bits, donc cette chaîne de 8 Go dépasse largement la mémoire adressable
Fonctionnement
select internal_objects_alloc_page_count
from sys.dm_db_task_space_usage
WHERE session_id = @@spid
Revenu
internal_objects_alloc_page_co
------------------------------
2144456
donc je suppose que tout cela est simplement stocké dans les LOB
pages tempdb
sans validation de la longueur. La croissance du nombre de pages était entièrement associée à l' SET @y = REPLICATE(@y,92681);
instruction. L'affectation initiale des variables à @y
et le LEN
calcul ne l'ont pas augmenté.
La raison de mentionner cela est que le nombre de pages est largement supérieur à ce à quoi je m'attendais. En supposant une page de 8 Ko, cela équivaut à 16,36 Go, ce qui est évidemment plus ou moins le double de ce qui semble nécessaire. Je suppose que cela est probablement dû à l'inefficacité de l'opération de concaténation de chaînes qui nécessite de copier la totalité de la chaîne énorme et d'ajouter un morceau à la fin plutôt que de pouvoir ajouter à la fin de la chaîne existante. Malheureusement, pour le moment, la .WRITE
méthode n'est pas prise en charge pour les variables varchar (max).
Une addition
J'ai également testé le comportement avec la concaténation nvarchar(max) + nvarchar(max)
et nvarchar(max) + varchar(max)
. Les deux permettent de dépasser la limite de 2 Go. Essayer de stocker ensuite les résultats de ceci dans une table échoue alors à Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
nouveau avec le message d'erreur . Le script pour cela est ci-dessous (peut prendre du temps à s'exécuter).
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
declare @x varchar(max) = 'XX'; SELECT LEN(REPLICATE(@x,2147483647))
donne4294967294
pour moi mais prend beaucoup de temps à courir - même après leSELECT
retour, donc je ne sais pas à quoi sert ce temps supplémentaire.