À tout moment dans le passé, si quelqu'un m'avait demandé la taille maximale d'un varchar(max)
, j'aurais dit 2 Go, ou recherché un chiffre plus exact (2 ^ 31-1 ou 2147483647).
Cependant, dans certains tests récents, j'ai découvert que les varchar(max)
variables peuvent apparemment dépasser cette taille:
create table T (
Val1 varchar(max) not null
)
go
declare @KMsg varchar(max) = REPLICATE('a',1024);
declare @MMsg varchar(max) = REPLICATE(@KMsg,1024);
declare @GMsg varchar(max) = REPLICATE(@MMsg,1024);
declare @GGMMsg varchar(max) = @GMsg + @GMsg + @MMsg;
select LEN(@GGMMsg)
insert into T(Val1) select @GGMMsg
select LEN(Val1) from T
Résultats:
(no column name)
2148532224
(1 row(s) affected)
Msg 7119, Level 16, State 1, Line 6
Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
The statement has been terminated.
(no column name)
(0 row(s) affected)
Donc, étant donné que je sais maintenant qu'une variable peut dépasser la barrière de 2 Go, est-ce que quelqu'un sait quelle est la limite réelle pour une varchar(max)
variable?
(Test ci-dessus terminé sur SQL Server 2008 (pas R2). Je serais intéressé de savoir s'il s'applique à d'autres versions)
sql-server
tsql
Damien_The_Unbeliever
la source
la source
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.Réponses:
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 avecle code ci-dessous échoue avec
Cependant, il semble que ces limitations aient été tranquillement levées. En 2008
Retour
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
Revenu
donc je suppose que tout cela est simplement stocké dans les
LOB
pagestempdb
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 leLEN
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)
etnvarchar(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).la source
varchar
valeurs de plus de 8 000 caractères dans les chaînes littérales du code, à condition que vous n'essayiez pas de le placer dans une variable ou unevarchar
colonne.EDIT : Après une enquête plus approfondie, mon hypothèse initiale selon laquelle il s'agissait d'une anomalie (bogue?) De la
declare @var datatype = value
syntaxe est incorrecte.J'ai modifié votre script pour 2005 car cette syntaxe n'est pas prise en charge, puis j'ai essayé la version modifiée en 2008. En 2005, j'obtiens le
Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
message d'erreur. En 2008, le script modifié réussit toujours.la source
Attempting to grow...
erreur sur laset @GGMMsg=...
déclaration. En 2008, le scénario est réussi.