Ich habe folgende Fehlermeldung beim Ausführen einer SQL-Datei mit ca. 26 MB auf SQL Server 2005:
%Vor%Ich arbeite mit 4GB RAM, 64Bit Windows 7 Ultimate, Core2Duo T6400 (2GHz) ...
Gibt es eine Möglichkeit, es auszuführen, ohne diese Nachricht zu erhalten (vielleicht zwinge SQL Server, Swap-Datei zu verwenden?) oder eine Möglichkeit, es in Teilen (wie 100 Abfragen pro Zeit) auszuführen ...
Die Datei ist im Grunde genommen eine CREATE TABLE gefolgt von tausend INSERT-Abfragen und ich habe viele davon (konvertierte .DBF-Dateien in SQL-Abfragen mit ABC DBF Converter)
Jede Idee wird sehr geschätzt!
Diese Frage scheint tatsächlich immer wieder hier aufzutauchen. Mark hat die richtige (und am häufigsten angestellt) antworten, aber lassen Sie mich versuchen, was ich kann, um dies klarer zu machen.
Die Fehlermeldung ist ein wenig irreführend. SQL Server teilt Ihnen mit, dass nicht genügend Arbeitsspeicher vorhanden ist, um die Abfrage ausführen zu können . Es bedeutet jedoch, dass es nicht genügend Arbeitsspeicher zum Parsen der Abfrage hat.
Wenn ausgeführt wird die Abfrage, SQL Server kann alle gewünschten - Gigabytes bei Bedarf verwenden. Parsing ist eine andere Geschichte; Der Server muss einen Parse-Baum erstellen, und dafür ist nur sehr wenig Speicher verfügbar. Ich habe nie das tatsächliche Limit irgendwo dokumentiert gefunden, aber für eine typische Menge von INSERT
-Anweisungen kann es nicht mehr als ein paar MB gleichzeitig verarbeiten.
Es tut mir leid, Ihnen das zu sagen, aber Sie können nicht machen, dass SQL Server dieses Skript genau so ausführt, wie es geschrieben wurde. Kein Weg, nein wie, egal welche Einstellungen du änderst. Sie haben jedoch eine Reihe von Optionen, um es zu umgehen:
Insbesondere haben Sie drei Optionen:
Verwenden Sie GO
-Anweisungen. Dies wird von SSMS und verschiedenen anderen Tools als Batch-Separator verwendet. Anstatt dass ein einzelner Parserbaum für das gesamte Skript generiert wird, werden für jedes Segment des Stapels individuelle Parsebäume erzeugt, die durch GO
getrennt sind. Das ist es, was die meisten Leute tun, und es ist sehr einfach, das Skript trotzdem transaktionssicher zu machen, wie andere gezeigt haben und ich werde es hier nicht wiederholen.
Anstatt ein massives Skript zum Einfügen aller Zeilen zu erstellen, behalten Sie die Daten in einer Textdatei (d. h. durch Kommas getrennt). Dann importieren Sie es mit dem bcp-Dienstprogramm . Wenn dies "skriptfähig" sein soll - dh der Import muss im selben Skript / derselben Transaktion erfolgen wie die CREATE TABLE
-Anweisung, dann verwenden Sie BULK INSERT stattdessen. Obwohl BULK INSERT
eine nicht geloggte Operation ist, ob Sie es glauben oder nicht, kann sie trotzdem in einem BEGIN TRAN
/ COMMIT TRAN
Block platziert werden.
Wenn Sie wirklich möchten, dass INSERT
eine protokollierte Operation ist und die Einfügungen nicht in Stapeln erfolgen sollen, können Sie OPENROWSET , um eine Textdatei, eine Excel-Datei usw. als Ad-hoc-Tabelle zu öffnen und diese dann in Ihre neu erstellte Tabelle einzufügen . Ich bin normalerweise nicht bereit, die Verwendung von OPENROWSET
zu empfehlen, aber da dies eindeutig ein Verwaltungsskript ist, ist es nicht wirklich ein großes Problem.
Bisherige Kommentare deuten darauf hin, dass Sie sich mit # 1 unbehaglich fühlen, obwohl dies möglicherweise auf eine falsche Annahme zurückzuführen ist, dass dies nicht in einer einzigen Transaktion geschehen kann. In diesem Fall sehen Sie Thomas die Antwort. Aber wenn Sie auf dem richtigen Weg sind, schlage ich vor, mit # 2 eine Textdatei zu erstellen und BULK INSERT
zu verwenden. Ein Beispiel für ein "sicheres" Skript wäre:
Dies hilft hoffentlich, Sie auf den richtigen Weg zu bringen. Ich bin mir ziemlich sicher, dass dies alle verfügbaren "in the box" -Optionen abdeckt - darüber hinaus müssten Sie anfangen, tatsächliche Anwendungsprogramme oder Shell-Skripte zu schreiben, um die Arbeit zu erledigen, und ich denke nicht, dass diese Komplexität der Fall ist wirklich gerechtfertigt hier.
Darüber hinaus Sprengen GO Anweisungen jede so viele Datensätze, wenn Sie besorgt sind über die ganze Sache läuft oder zurückrollen dann verwenden Sie eine Transaktion wie folgt:
%Vor%Wenn XACT_ABORT auf ON gesetzt ist, wird bei jeder ausfallenden INSERT-Anweisung die gesamte Transaktion zurückgesetzt.
Sie können DBCC-Befehle zwischen Ihren SQL-Abfragen hinzufügen wie:
%Vor%Dies wird helfen, Speicher freizugeben. Außerdem veröffentlicht Microsoft einen Hotfix, um dieses Problem in Sql Server 2005 zu beheben ( hier ). Versuchen Sie, das Hotfix \ Service Pack zu installieren.
Tags und Links memory sql-server-2005