Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Максимален размер на променлива varchar(max).

Доколкото мога да кажа, няма горна граница през 2008 г.

В SQL Server 2005 кодът във вашия въпрос е неуспешен при присвояването на @GGMMsg променлива с

Опит за увеличаване на LOB над максималния разрешен размер от 2 147 483 647 байта.

кодът по-долу не работи с

РЕПЛИЦИРАНЕ:Дължината на резултата надвишава ограничението за дължина (2GB) на целевия голям тип.

Изглежда обаче, че тези ограничения тихомълком са премахнати. През 2008 г.

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

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

SELECT LEN(@y) 

Връща

8589767761

Пуснах това на моята 32-битова настолна машина, така че този низ от 8 GB е доста повече от адресируемата памет

Работи

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

Върнато

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

така че предполагам, че всичко това просто се съхранява в LOB страници в tempdb без валидиране на дължината. Нарастването на броя на страниците беше свързано с SET @y = REPLICATE(@y,92681); изявление. Първоначалното присвояване на променлива на @y и LEN изчислението не увеличи това.

Причината да спомена това е, че броят на страниците е много повече, отколкото очаквах. Ако приемем страница от 8KB, тогава това работи при 16,36 GB, което очевидно е повече или по-малко двойно повече от необходимото. Предполагам, че това вероятно се дължи на неефективността на операцията за конкатенация на низове, която трябва да копира целия огромен низ и да добави парче към края, вместо да може да добави към края на съществуващия низ. За съжаление в момента .WRITE методът не се поддържа за varchar(max) променливи.

Допълнение

Тествах също поведението с конкатенация nvarchar(max) + nvarchar(max) и nvarchar(max) + varchar(max) . И двете позволяват превишаване на ограничението от 2GB. Опитът след това да съхрани резултатите от това в таблица, след това се проваля със съобщението за грешка Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes. отново. Скриптът за това е по-долу (може да отнеме много време за изпълнение).

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изявление на SQL CASE

  2. Как да генерирате drop Unique Constraint скриптове в база данни на SQL Server - SQL Server / TSQL Урок, част 99

  3. Трябва да предам имена на колони, използвайки променлива в оператора за избор в процедурата на магазин, но не мога да използвам динамична заявка

  4. Разделете низ, разделен със запетая, и вмъкнете в таблица (int)

  5. Правилно използване на транзакциите в SQL Server