sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server 2005 Fel 701 - slut på minne

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:

  1. 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 av GO . 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.

  2. 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 om BULK INSERT är en icke-loggad operation, tro det eller ej, den kan fortfarande placeras inom en BEGIN TRAN / COMMIT TRAN blockera.

  3. 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 av OPENROWSET , 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.



  1. Primära och främmande nycklar i pgAdmin

  2. Skripta över ssh genom kitt på windows

  3. Hur man frågar denna utdata i SQL-server

  4. Vad är den maximala storleken på int(10) i Mysql