Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Maksymalny rozmiar zmiennej varchar(max)

O ile wiem, w 2008 roku nie ma górnego limitu.

W SQL Server 2005 kod w twoim pytaniu kończy się niepowodzeniem przy przypisaniu do @GGMMsg zmienna z

Próba zwiększenia LOB poza maksymalny dozwolony rozmiar 2 147 483 647 bajtów.

poniższy kod nie powiedzie się z

REPLICATE:Długość wyniku przekracza limit długości (2 GB) docelowego typu dużego.

Wydaje się jednak, że te ograniczenia zostały po cichu zniesione. W 2008

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

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

SELECT LEN(@y) 

Zwroty

8589767761

Uruchomiłem to na moim 32-bitowym komputerze stacjonarnym, więc ten ciąg 8 GB to znacznie więcej pamięci adresowalnej

Bieganie

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

Zwrócone

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

więc zakładam, że to wszystko zostanie zapisane w LOB strony w tempdb bez weryfikacji długości. Wzrost liczby stron był powiązany z SET @y = REPLICATE(@y,92681); oświadczenie. Początkowe przypisanie zmiennej do @y i LEN obliczenia nie zwiększyły tego.

Powodem, dla którego o tym wspominam, jest to, że liczba stron jest znacznie większa, niż się spodziewałem. Zakładając, że strona 8 KB, to daje to 16,36 GB, co oczywiście jest mniej więcej dwa razy większe niż wydaje się konieczne. Spekuluję, że jest to prawdopodobnie spowodowane nieefektywnością operacji łączenia ciągów, która wymaga skopiowania całego ogromnego ciągu i dodania kawałka na końcu, zamiast możliwości dodania go na końcu istniejącego ciągu. Niestety w tej chwili .WRITE metoda nie jest obsługiwana dla zmiennych varchar(max).

Dodanie

Testowałem również zachowanie za pomocą łączenia nvarchar(max) + nvarchar(max) i nvarchar(max) + varchar(max) . Oba pozwalają na przekroczenie limitu 2 GB. Próba zapisania wyników tego w tabeli kończy się jednak niepowodzeniem z komunikatem o błędzie Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes. ponownie. Skrypt do tego znajduje się poniżej (uruchomienie może zająć dużo czasu).

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. scope_identity a ident_current

  2. Zapytanie o listę wszystkich procedur składowanych

  3. Jak utworzyć alias typu danych zdefiniowanego przez użytkownika w SQL Server przy użyciu T-SQL

  4. Podczas wykonywania procedury składowanej, jaka jest korzyść z używania CommandType.StoredProcedure w porównaniu z używaniem CommandType.Text?

  5. Wykonaj wyzwalacz tylko wtedy, gdy niektóre kolumny są aktualizowane (SQL Server)