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

SQL Server 2005 Грешка 701 - липса на памет

Този въпрос всъщност изглежда се появява толкова често тук. Маркиране има правилния (и най-често използван) отговор, но нека се опитам да добавя каквото мога, за да направя това по-ясно.

Съобщението за грешка е малко подвеждащо. SQL Server ви казва, че няма достатъчно памет за изпълнение заявката, но това, което всъщност означава е, че няма достатъчно памет за анализ заявката.

Когато става въпрос за бягане заявката, SQL Server може да използва всичко, което иска - гигабайти, ако е необходимо. Разборът е друга история; сървърът трябва да изгради дърво за анализ и има само много ограничено количество налична памет за това. Никога не съм намирал действителния лимит, документиран никъде, освен за типична партида, пълна с INSERT изрази, той не може да обработва повече от няколко MB наведнъж.

Така че съжалявам, че ви го казвам, но вие не можете накарайте SQL Server да изпълни този скрипт точно както е написан. Няма начин, няма как, няма значение какви настройки променяте. Имате обаче редица опции да го заобиколите:

По-конкретно, имате три възможности:

  1. Използвайте GO изявления. Това се използва от SSMS и различни други инструменти като разделител на партиди. Вместо да се генерира едно дърво за анализ за целия скрипт, отделни дървета за анализ се генерират за всеки сегмент от пакета, разделени от GO . Това е, което правят повечето хора и е много лесно да направите скрипта транзакционно безопасен, както демонстрираха други и няма да повтарям тук.

  2. Вместо да генерирате масивен скрипт за вмъкване на всички редове, дръжте данните в текстов файл (т.е. разделени със запетая). След това го импортирайте с помощта на помощната програма bcp . Ако имате нужда това да бъде "скриптируемо" - т.е. импортирането трябва да се случи в същия скрипт/транзакция като CREATE TABLE израз, след което използвайте BULK INSERT вместо. Въпреки че BULK INSERT е нерегистрирана операция, вярвате или не, тя все още може да бъде поставена в рамките на BEGIN TRAN / COMMIT TRAN блокирай.

  3. Ако наистина, наистина искате INSERT за да бъде регистрирана операция и не искате вмъкванията да се извършват на партиди, тогава можете да използвате OPENROWSET за да отворите текстов файл, файл на Excel и т.н. като ad-hoc "таблица" и след това да го вмъкнете в новосъздадената таблица. Обикновено не искам да препоръчвам използването на OPENROWSET , но тъй като това очевидно е административен скрипт, всъщност не е голям проблем.

Предишни коментари показват, че се чувствате неудобно с #1, въпреки че това може да се дължи само на неправилно предположение, че не може да се направи в една транзакция, в който случай вижте Томас отговорът на. Но ако сте твърдо решени да тръгнете по друг начин, предлагам да отидете с #2, да създадете текстов файл и да използвате BULK INSERT . Пример за "безопасен" скрипт би бил:

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

Надяваме се, че това ще ви помогне да поемете по правилния път. Почти съм сигурен, че това покрива всичките ви налични опции „в кутията“ - освен тези, ще трябва да започнете да пишете реални приложни програми или скриптове на обвивка, за да свършите работата, и не мисля, че това ниво на сложност е тук наистина е оправдано.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Транспонираща таблица

  2. Преброяване на нови клиенти на месец

  3. Текуща сума за плащания по издадените фактури

  4. как да променя нивото на изолация?

  5. Няма споделени набори от данни в Solution Explorer на студио за разработка на бизнес разузнаване