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:
-
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 afGO
. 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. -
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. SelvomBULK INSERT
er en ikke-logget operation, tro det eller ej, den kan stadig placeres i enBEGIN TRAN
/COMMIT TRAN
blokere. -
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.