sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server 2005 Fejl 701 - tør for hukommelse

Dette spørgsmål ser faktisk ud til at dukke op af og til her. Mark har det korrekte (og mest anvendte) svar, men lad mig prøve at tilføje, hvad jeg kan for at gøre dette klarere.

Fejlmeddelelsen er lidt misvisende. SQL Server fortæller dig, at den ikke har nok hukommelse til at køre forespørgslen, men hvad det egentlig betyder er, at det ikke har nok hukommelse til at parse forespørgslen.

Når det kommer til løb forespørgslen, kan SQL Server bruge alt, hvad den vil - gigabyte om nødvendigt. Parsing er en anden historie; serveren skal bygge et parsetræ, og der er kun en meget begrænset mængde hukommelse til rådighed til det. Jeg har aldrig fundet den faktiske grænse dokumenteret andre steder end for en typisk batch fuld af INSERT udsagn, kan den ikke håndtere mere end et par MB ad gangen.

Så jeg er ked af at fortælle dig dette, men du kan ikke få SQL Server til at udføre dette script præcis som det er skrevet. Ingen måde, nej hvordan, er ligegyldigt, hvilke indstillinger du justerer. Du har dog en række muligheder for at omgå det:

Specifikt har du tre muligheder:

  1. Brug GO udsagn. Dette bruges af SSMS og forskellige andre værktøjer som en batch-separator. I stedet for at der genereres et enkelt parsetræ for hele scriptet, genereres individuelle parsetræer for hvert segment af batchen adskilt af GO . Dette er, hvad de fleste mennesker gør, og det er meget enkelt stadig at gøre scriptet transaktionssikkert, som andre har vist, og jeg vil ikke gentage her.

  2. I stedet for at generere et massivt script til at indsætte alle rækkerne, skal du beholde dataene i en tekstfil (dvs. kommasepareret). Importer det derefter ved hjælp af bcp-værktøjet . Hvis du har brug for, at dette er "scriptable" - dvs. importen skal ske i samme script/transaktion som CREATE TABLE sætning, og brug derefter BULK INSERT i stedet. Selvom BULK INSERT er en ikke-logget operation, tro det eller ej, den kan stadig placeres i en BEGIN TRAN / COMMIT TRAN blokere.

  3. Hvis du virkelig vil have INSERT for at være en logget operation og ikke ønsker, at indsættelserne skal ske i batches, så kan du bruge ÅBN ROWSET at åbne en tekstfil, excel-fil osv. som en ad-hoc "tabel", og så indsætte denne i din nyoprettede tabel. Jeg bryder mig normalt ikke om nogensinde at anbefale brugen af ​​OPENROWSET , men da dette helt klart er et administrativt script, er det egentlig ikke et stort problem.

Tidligere kommentarer tyder på, at du er utilpas med #1, selvom det måske bare skyldes en forkert antagelse om, at det ikke kan gøres i en enkelt transaktion, i så fald se Thomas 's svar. Men hvis du er klar til at gå en anden vej, foreslår jeg, at du går med #2, laver en tekstfil og bruger BULK INSERT . Et eksempel på et "sikkert" script ville være:

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

Forhåbentlig hjælper dette med at bringe dig på rette vej. Jeg er ret sikker på, at dette dækker alle dine tilgængelige "i boksen"-muligheder - ud over disse, skulle du begynde at skrive faktiske applikationsprogrammer eller shell-scripts for at udføre arbejdet, og jeg tror ikke, at det kompleksitetsniveau er virkelig berettiget her.



  1. sum og generer serier virker ikke i postgresql

  2. Sådan læser du alle filer i en Oracle Directory med PL/SQL og opdaterer en BLOB-kolonne

  3. Trigger kan ikke læse tabellen, efter at være blevet affyret af den samme tabel

  4. Fejl under tilslutning til database på hostet server