Този въпрос всъщност изглежда се появява толкова често тук. Маркиране има правилния (и най-често използван) отговор, но нека се опитам да добавя каквото мога, за да направя това по-ясно.
Съобщението за грешка е малко подвеждащо. SQL Server ви казва, че няма достатъчно памет за изпълнение заявката, но това, което всъщност означава е, че няма достатъчно памет за анализ заявката.
Когато става въпрос за бягане заявката, SQL Server може да използва всичко, което иска - гигабайти, ако е необходимо. Разборът е друга история; сървърът трябва да изгради дърво за анализ и има само много ограничено количество налична памет за това. Никога не съм намирал действителния лимит, документиран никъде, освен за типична партида, пълна с INSERT
изрази, той не може да обработва повече от няколко MB наведнъж.
Така че съжалявам, че ви го казвам, но вие не можете накарайте SQL Server да изпълни този скрипт точно както е написан. Няма начин, няма как, няма значение какви настройки променяте. Имате обаче редица опции да го заобиколите:
По-конкретно, имате три възможности:
-
Използвайте
GO
изявления. Това се използва от SSMS и различни други инструменти като разделител на партиди. Вместо да се генерира едно дърво за анализ за целия скрипт, отделни дървета за анализ се генерират за всеки сегмент от пакета, разделени отGO
. Това е, което правят повечето хора и е много лесно да направите скрипта транзакционно безопасен, както демонстрираха други и няма да повтарям тук. -
Вместо да генерирате масивен скрипт за вмъкване на всички редове, дръжте данните в текстов файл (т.е. разделени със запетая). След това го импортирайте с помощта на помощната програма bcp . Ако имате нужда това да бъде "скриптируемо" - т.е. импортирането трябва да се случи в същия скрипт/транзакция като
CREATE TABLE
израз, след което използвайте BULK INSERT вместо. Въпреки чеBULK INSERT
е нерегистрирана операция, вярвате или не, тя все още може да бъде поставена в рамките наBEGIN TRAN
/COMMIT TRAN
блокирай. -
Ако наистина, наистина искате
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
Надяваме се, че това ще ви помогне да поемете по правилния път. Почти съм сигурен, че това покрива всичките ви налични опции „в кутията“ - освен тези, ще трябва да започнете да пишете реални приложни програми или скриптове на обвивка, за да свършите работата, и не мисля, че това ниво на сложност е тук наистина е оправдано.