Denna fråga tycks faktiskt dyka upp då och då här. Mark har det korrekta (och mest använda) svaret, men låt mig försöka lägga till vad jag kan för att göra detta tydligare.
Felmeddelandet är lite missvisande. SQL Server säger till dig att den inte har tillräckligt med minne för att köras frågan, men vad den egentligen betyder är att den inte har tillräckligt med minne för att tolka frågan.
När det gäller löpning frågan kan SQL Server använda allt den vill - gigabyte om det behövs. Att analysera är en annan historia; servern måste bygga ett parseträd och det finns bara en mycket begränsad mängd minne tillgängligt för det. Jag har aldrig hittat den faktiska gränsen dokumenterad någon annanstans än för en typisk sats full av INSERT
uttalanden kan den inte hantera mer än några MB åt gången.
Så jag är ledsen att jag ska berätta detta men du kan inte få SQL Server att köra det här skriptet precis som det är skrivet. Inget sätt, nej hur, spelar ingen roll vilka inställningar du justerar. Du har dock ett antal alternativ för att komma runt det:
Specifikt har du tre alternativ:
-
Använd
GO
uttalanden. Detta används av SSMS och olika andra verktyg som en batchseparator. Istället för att ett enda analysträd genereras för hela skriptet, genereras individuella analysträd för varje segment av batchen åtskilda avGO
. Detta är vad de flesta människor gör, och det är väldigt enkelt att fortfarande göra skriptet transaktionssäkert, vilket andra har visat och jag kommer inte att upprepa här. -
Istället för att skapa ett massivt skript för att infoga alla rader, behåll data i en textfil (dvs kommaseparerad). Importera den sedan med bcp-verktyget . Om du vill att detta ska vara "skriptbart" - dvs importen måste ske i samma skript/transaktion som
CREATE TABLE
uttalande, använd sedan BULK INSERT istället. Även omBULK INSERT
är en icke-loggad operation, tro det eller ej, den kan fortfarande placeras inom enBEGIN TRAN
/COMMIT TRAN
blockera. -
Om du verkligen vill ha
INSERT
för att vara en loggad operation och inte vill att infogningen ska ske i omgångar kan du använda ÖPPNA ROWSET att öppna en textfil, excel-fil, etc. som en ad-hoc "tabell", och sedan infoga denna i din nyskapade tabell. Jag avskyr normalt att någonsin rekommendera användningen avOPENROWSET
, men eftersom detta helt klart är ett administrativt manus är det egentligen inget större problem.
Tidigare kommentarer tyder på att du är obekväm med #1, även om det bara kan bero på ett felaktigt antagande att det inte kan göras i en enda transaktion, i så fall se Thomas
s svar. Men om du inte är sugen på att gå en annan väg, föreslår jag att du går med #2, skapar en textfil och använder BULK INSERT
. Ett exempel på ett "säkert" skript skulle vara:
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
Förhoppningsvis hjälper detta dig att komma på rätt spår. Jag är ganska säker på att detta täcker alla dina tillgängliga "i lådan"-alternativ - utöver dessa måste du börja skriva faktiska applikationsprogram eller skalskript för att göra jobbet, och jag tror inte att den komplexitetsnivån är verkligen motiverat här.