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

Limit maksymalnej liczby wierszy konstruktora wartości tabeli w Select

Nie ma odpowiedniego stałego limitu kodowego (65 536 * Rozmiar pakietu sieciowego 4 KB to 268 MB, a długość Twojego skryptu jest daleko od tego), chociaż niewskazane jest stosowanie tej metody w przypadku dużej liczby wierszy.

Wyświetlany błąd jest zgłaszany przez narzędzia klienta, a nie przez program SQL Server. Jeśli konstruujesz ciąg SQL w dynamicznej kompilacji SQL, możesz przynajmniej zacząć pomyślnie

DECLARE @SQL NVARCHAR(MAX) = '(100,200,300),
';

SELECT @SQL = 'SELECT * FROM (VALUES ' + REPLICATE(@SQL, 1000000) + '
(100,200,300)) tc (proj_d, period_sid, val)';

SELECT @SQL AS [processing-instruction(x)]
FOR XML PATH('')

SELECT DATALENGTH(@SQL) / 1048576.0 AS [Length in MB] --30.517705917

EXEC(@SQL);

Chociaż zabiłem powyższe po ~30 minutach kompilacji i nadal nie spowodowało to awarii. Dosłowne wartości muszą być przechowywane w samym planie jako tabela stałych, a SQL Server wydaje dużo czasu próbując również wyprowadzić ich właściwości.

SSMS to aplikacja 32-bitowa i rzuca std::bad_alloc wyjątek podczas analizowania wsadu

Próbuje wypchnąć element na wektor Tokena, który osiągnął pojemność, a jego próba zmiany rozmiaru kończy się niepowodzeniem z powodu niedostępności wystarczająco dużego, ciągłego obszaru pamięci. Tak więc oświadczenie nigdy nie dociera do serwera.

Pojemność wektora rośnie za każdym razem o 50% (tj. zgodnie z sekwencją tutaj ). Pojemność, do której wektor musi się rozwijać, zależy od układu kodu.

Następujące potrzeby muszą wzrosnąć z pojemności 19 do 28.

SELECT * FROM (VALUES (100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300)) tc (proj_d, period_sid, val)

a poniższe wymagają tylko rozmiaru 2

SELECT * FROM (VALUES (100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300)) tc (proj_d, period_sid, val)

Poniższe wymaga pojemności> 63 i <=94.

SELECT *
FROM   (VALUES 
      (100,
       200,
       300),
      (100,
       200,
       300),
      (100,
       200,
       300),
      (100,
       200,
       300),
      (100,
       200,
       300),
      (100,
       200,
       300)
       ) tc (proj_d, period_sid, val) 

Dla miliona wierszy ułożonych jak w przypadku 1 pojemność wektora musi wzrosnąć do 3 543 306.

Może się okazać, że jedno z poniższych pozwoli na pomyślne parsowanie po stronie klienta.

  1. Zmniejsz liczbę łamań wierszy.
  2. Ponowne uruchomienie SSMS w nadziei, że żądanie dużej pamięci ciągłej powiedzie się, gdy fragmentacja przestrzeni adresowej jest mniejsza.

Jednak nawet jeśli pomyślnie wyślesz go na serwer, zakończy się to tylko zabiciem serwera podczas generowania planu wykonania, jak omówiono powyżej.

Znacznie lepiej będzie załadować tabelę za pomocą kreatora importu i eksportu. Jeśli musisz to zrobić w TSQL, zobaczysz, że rozbicie go na mniejsze partie i/lub użycie innej metody, takiej jak niszczenie XML, będzie działać lepiej niż konstruktory o wartościach tabel. Na przykład poniższy kod jest wykonywany w ciągu 13 sekund na moim komputerze (chociaż jeśli używasz SSMS, prawdopodobnie nadal będziesz musiał podzielić się na wiele partii, zamiast wklejać ogromny literał ciągu XML).

DECLARE @S NVARCHAR(MAX) = '<x proj_d="100" period_sid="200" val="300" />
' ; 

DECLARE @Xml XML = REPLICATE(@S,1000000);

SELECT 
    x.value('@proj_d','int'),
    x.value('@period_sid','int'),
    x.value('@val','int')
FROM @Xml.nodes('/x') c(x)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Podziel słowa z wielką literą w sql

  2. Wybierz ostatnie 30 dni z zapytaniem sql

  3. Jak zainstalować SQL Server w systemie Windows

  4. Uzyskaj następne minimum, większe lub równe danej wartości dla każdej grupy

  5. Różnica czasu SQL między dwiema datami daje wynik gg:mm:ss