Wenn mich in der Vergangenheit jemand nach der maximalen Größe für a gefragt hätte varchar(max)
, hätte ich 2 GB gesagt oder eine genauere Zahl nachgeschlagen (2 ^ 31-1 oder 2147483647).
Bei einigen kürzlich durchgeführten Tests habe ich jedoch festgestellt, dass varchar(max)
Variablen diese Größe anscheinend überschreiten können:
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
Ergebnisse:
(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)
Angesichts der Tatsache , dass ich jetzt weiß, dass eine Variable die 2-GB-Grenze überschreiten kann, weiß jemand, wie hoch das tatsächliche Limit für eine varchar(max)
Variable ist?
(Der obige Test wurde unter SQL Server 2008 (nicht R2) abgeschlossen. Es würde mich interessieren, ob er für andere Versionen gilt.)
sql-server
tsql
Damien_The_Unbeliever
quelle
quelle
declare @x varchar(max) = 'XX'; SELECT LEN(REPLICATE(@x,2147483647))
gibt4294967294
für mich aber dauert lange zu laufen - auch nachdem derSELECT
zurückgekehrt ist, also nicht sicher, was diese zusätzliche Zeit damit verbracht wird.Antworten:
Soweit ich das beurteilen kann, gibt es 2008 keine Obergrenze.
In SQL Server 2005 schlägt der Code in Ihrer Frage bei der Zuordnung zur
@GGMMsg
Variablen mit fehlDer folgende Code schlägt mit fehl
Es scheint jedoch, dass diese Einschränkungen stillschweigend aufgehoben wurden. Im Jahr 2008
Kehrt zurück
Ich habe dies auf meinem 32-Bit-Desktop-Computer ausgeführt, sodass diese 8-GB-Zeichenfolge den adressierbaren Speicher weit übersteigt
Laufen
Ist zurückgekommen
Ich gehe also davon aus, dass dies alles nur auf
LOB
Seitentempdb
ohne Validierung der Länge gespeichert wird . Das Wachstum der Seitenzahl war alle mit derSET @y = REPLICATE(@y,92681);
Aussage verbunden. Die anfängliche Variablenzuordnung zu@y
und dieLEN
Berechnung haben dies nicht erhöht.Der Grund für die Erwähnung ist, dass die Seitenzahl enorm höher ist als ich erwartet hatte. Unter der Annahme einer 8-KB-Seite ergibt sich eine Größe von 16,36 GB, was offensichtlich mehr oder weniger doppelt so hoch ist, wie es notwendig erscheint. Ich spekuliere, dass dies wahrscheinlich auf die Ineffizienz der Zeichenfolgenverkettungsoperation zurückzuführen ist, bei der die gesamte große Zeichenfolge kopiert und ein Teil an das Ende angehängt werden muss, anstatt das Ende der vorhandenen Zeichenfolge hinzufügen zu können. Leider wird die
.WRITE
Methode derzeit nicht für varchar (max) -Variablen unterstützt .Zusatz
Ich habe auch das Verhalten mit Verkettung
nvarchar(max) + nvarchar(max)
und getestetnvarchar(max) + varchar(max)
. In beiden Fällen kann das 2-GB-Limit überschritten werden. Der Versuch, die Ergebnisse davon in einer Tabelle zu speichern, schlägt jedoch mit der FehlermeldungAttempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
erneut fehl . Das Skript dafür finden Sie weiter unten (die Ausführung kann lange dauern).quelle
varchar
Werte enthalten, die länger als 8000 Zeichen in Literalzeichenfolgen im Code sind, solange Sie nicht versucht haben, sie in eine Variable odervarchar
Spalte einzufügen.EDIT : Nach weiteren Untersuchungen ist meine ursprüngliche Annahme, dass dies eine Anomalie (Fehler?) Der
declare @var datatype = value
Syntax war, falsch.Ich habe Ihr Skript für 2005 geändert, da diese Syntax nicht unterstützt wird, und dann 2008 die geänderte Version ausprobiert. 2005 wird die
Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
Fehlermeldung angezeigt. Im Jahr 2008 ist das geänderte Skript immer noch erfolgreich.quelle
Attempting to grow...
Fehler auf derset @GGMMsg=...
Erklärung. Im Jahr 2008 ist das Skript erfolgreich.