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

SQL Server 2005 Błąd 701 - brak pamięci

Wydaje się, że to pytanie pojawia się tu od czasu do czasu. Mark ma poprawną (i najczęściej używaną) odpowiedź, ale spróbuję dodać, co mogę, aby to było jaśniejsze.

Komunikat o błędzie jest trochę mylący. SQL Server informuje, że nie ma wystarczającej ilości pamięci, aby uruchomić zapytanie, ale tak naprawdę oznacza to, że nie ma wystarczającej ilości pamięci, aby przeanalizować zapytanie.

Jeśli chodzi o bieganie kwerendy SQL Server może wykorzystać wszystko, czego chce - w razie potrzeby gigabajty. Parsowanie to inna historia; serwer musi zbudować drzewo parsowania, a na to dostępna jest tylko bardzo ograniczona ilość pamięci. Nigdy nie znalazłem faktycznego udokumentowanego limitu nigdzie poza typową partią pełną INSERT oświadczenia, nie może obsłużyć więcej niż kilka MB na raz.

Przykro mi, że ci to mówię, ale nie możesz sprawiają, że SQL Server wykonuje ten skrypt dokładnie tak, jak jest napisany. Nie ma mowy, nie ma jak, nie ma znaczenia, jakie ustawienia dostosujesz. Masz jednak kilka możliwości obejścia tego problemu:

W szczególności masz trzy opcje:

  1. Użyj GO sprawozdania. Jest to używane przez SSMS i różne inne narzędzia jako separator wsadowy. Zamiast pojedynczego drzewa analizowania generowanego dla całego skryptu, dla każdego segmentu wsadu oddzielonego znakiem GO generowane są pojedyncze drzewa analizowania . To jest to, co robi większość ludzi, i nadal bardzo łatwo jest uczynić skrypt bezpiecznym transakcyjnie, jak pokazali inni i nie będę tutaj powtarzał.

  2. Zamiast generować ogromny skrypt do wstawiania wszystkich wierszy, zachowaj dane w pliku tekstowym (tj. oddzielone przecinkami). Następnie zaimportuj go za pomocą narzędzia bcp . Jeśli potrzebujesz, aby było to „skryptowalne” – tj. import musi odbywać się w tym samym skrypcie/transakcji, co CREATE TABLE oświadczenie, a następnie użyj WKŁADKA ZBIORCZA zamiast. Chociaż BULK INSERT jest operacją niezarejestrowaną, wierzcie lub nie, nadal można ją umieścić w BEGIN TRAN / COMMIT TRAN blokować.

  3. Jeśli naprawdę, naprawdę chcesz INSERT aby być zarejestrowaną operacją i nie chcesz, aby wstawienia odbywały się partiami, możesz użyć OPENROWSET aby otworzyć plik tekstowy, plik Excela itp. jako „tablicę” ad-hoc, a następnie wstawić go do nowo utworzonej tabeli. Zwykle niechętnie zalecam użycie OPENROWSET , ale ponieważ jest to wyraźnie skrypt administracyjny, nie stanowi to większego problemu.

Poprzednie komentarze sugerują, że czujesz się niekomfortowo z #1, chociaż może to wynikać tylko z błędnego założenia, że ​​nie można tego zrobić w pojedynczej transakcji, w takim przypadku zobacz Thomas odpowiedź. Ale jeśli nie masz ochoty iść w inną stronę, sugeruję przejście do punktu 2, utworzenie pliku tekstowego i użycie BULK INSERT . Przykładem „bezpiecznego” skryptu będzie:

BEGIN TRAN

BEGIN TRY

    CREATE TABLE MyTable (...)

    BULK INSERT  MyTable
    FROM 'C:\Scripts\Data\MyTableData.txt' 
    WITH (
        FIELDTERMINATOR = ',',
        ROWTERMINATOR = '\r\n',
        BATCHSIZE = 1000,
        MAXERRORS = 1
    )

    COMMIT

END TRY

BEGIN CATCH

    ROLLBACK

END CATCH

Mam nadzieję, że to pomoże Ci na właściwej drodze. Jestem prawie pewien, że obejmuje to wszystkie dostępne opcje "w pudełku" - poza nimi musiałbyś zacząć pisać rzeczywiste aplikacje lub skrypty powłoki, aby wykonać pracę, i nie sądzę, aby poziom złożoności był naprawdę uzasadnione.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Policz liczbę rekordów zwróconych przez grupę przez

  2. Utwórz konto pocztowe bazy danych w programie SQL Server (T-SQL)

  3. Jak mogę uniknąć używania Cursora do implementacji tego pseudokodu - SQL Server?

  4. nie można otworzyć, ponieważ jest to wersja 706. Ten serwer obsługuje wersję 662 i wcześniejsze. Ścieżka zmiany wersji nie jest obsługiwana

  5. Zmiana INT na BigInt