it-swarm.com.de

Wie führe ich ein großes Skript mit vielen Einfügungen aus, ohne dass der Speicher knapp wird?

Frage :

Ich habe ein Skript mit ungefähr 45.000 Einfügungen aus ausgewählten Anweisungen. Wenn ich versuche, es auszuführen, erhalte ich eine Fehlermeldung, dass mir der Speicher ausgeht. Wie kann ich dieses Skript zum Laufen bringen?

Kontext :

  1. Es wurden einige neue Datenfelder hinzugefügt, damit eine App mit einer anderen vom Client verwendeten App gut funktioniert.
  2. Vom Client wurde eine Tabelle mit Daten mit Daten abgerufen, mit denen aktuelle Datenelemente Werten für diese neuen Felder zugeordnet wurden.
  3. Konvertierte Tabelle zum Einfügen von Anweisungen.
  4. Wenn ich nur einige der Anweisungen ausführe, funktioniert dies, das gesamte Skript jedoch nicht.
  5. Nein, es gibt keine Tippfehler.

Wenn es eine andere Art gibt, wie ich diese Daten laden sollte, zögern Sie nicht, mich zu bestrafen und mich zu informieren.

28
spaghetticowboy

Die maximale Stapelgröße für SQL Server 2005 beträgt 65.536 * Network Packet Size (NPS), wobei NPS normalerweise 4 KB beträgt. Das entspricht 256 MB. Das würde bedeuten, dass Ihre Insert-Anweisungen durchschnittlich jeweils 5,8 KB groß sind. Das scheint nicht richtig zu sein, aber vielleicht gibt es dort fremde Räume oder etwas Ungewöhnliches.

Mein erster Vorschlag wäre, nach jeder INSERT-Anweisung eine "GO" -Anweisung einzufügen. Dadurch wird Ihr einzelner Stapel von 45.000 INSERT-Anweisungen in 45.000 separate Stapel aufgeteilt. Dies sollte leichter zu verdauen sein. Seien Sie vorsichtig, wenn einer dieser Beilagen ausfällt, fällt es Ihnen möglicherweise schwer, den Schuldigen zu finden. Vielleicht möchten Sie sich mit einer Transaktion schützen. Sie können diese Anweisungen schnell hinzufügen, wenn Ihr Editor über eine gute Such- und Ersetzungsfunktion (mit der Sie Rückgabezeichen wie\r\n suchen und ersetzen können) oder eine Makrofunktion verfügt.

Der zweite Vorschlag besteht darin, ein Wizard) zu verwenden, um die Daten direkt aus Excel zu importieren. Der Assistent erstellt hinter den Kulissen ein kleines SSIS-Paket für Sie und führt es dann aus Problem.

17
darin strait

BULK INSERT oder bcp scheinen geeignetere Optionen zu sein als 45.000 Einfügeanweisungen.

Wenn Sie sich an die Einfügeanweisungen halten müssen, würde ich einige Optionen in Betracht ziehen:

A: Verwenden Sie Transaktionen und verpacken Sie Stapel mit jeweils 100, 500 oder 1000 Anweisungen, um die Auswirkungen auf das Protokoll und den Stapel zu minimieren. z.B.

BEGIN TRANSACTION;
INSERT dbo.table(a, ...) SELECT 1, ...
INSERT dbo.table(a, ...) SELECT 2, ...
...
INSERT dbo.table(a, ...) SELECT 500, ...
COMMIT TRANSACTION;
GO

BEGIN TRANSACTION;
INSERT dbo.table(a, ...) SELECT 1, ...
INSERT dbo.table(a, ...) SELECT 2, ...
...
INSERT dbo.table(a, ...) SELECT 500, ...
COMMIT TRANSACTION;
GO

B: Verwenden Sie anstelle einzelner Einfügeanweisungen UNION ALL für 100 oder 500 Anweisungen gleichzeitig, z.

INSERT dbo.table(a, ...)
SELECT 1, ...
UNION ALL SELECT 2, ...
...
UNION ALL SELECT 500, ...
GO

INSERT dbo.table(a, ...)
SELECT 501, ...
UNION ALL SELECT 502, ...
...
UNION ALL SELECT 1000, ...
GO

Ich habe die Fehlerbehandlung der Kürze halber weggelassen, aber der Punkt ist, dass ich niemals versuchen würde, einen einzelnen Stapel von 45.000 einzelnen Anweisungen an SQL Server zu senden.

14
Aaron Bertrand

Ich bin nicht sicher, warum Sie den Speicherfehler erhalten, aber es gibt einen einfacheren Ansatz.

Wenn Sie die Daten aus der Tabelle in ein begrenztes Format (z. B. CSV) exportieren können, können Sie den Datenimport-Assistenten in SSMS verwenden, um die Daten für Sie einzufügen:

SSMS import data task.

9
datagod

Erstellen Sie mit mehreren SqlBulkCopy eine temporäre Tabelle. Fügen Sie neue Daten in die temporäre Tabelle ein und führen Sie die Daten in der temporären Tabelle mit der vorhandenen zusammen. Beispiel mit der C # SqlBulkCopy.WriteToServer-Methode (DataTable) . Ich hoffe es hilft

0
Hung Vu

Ja, das könnten wir tun, ich habe es mit einem [~ # ~] bcp [~ # ~] (Bulk Copy Program) -Ansatz versucht, um einen OutOfMemory Zu vermeiden = Problem.

Hinweis: Versucht unter SQL Server 2014.

In BCP müssen wir zuerst die Quellendatenbankdaten in die Datei bcp (im lokalen Verzeichnisordner) exportieren und dann diese Datei bcp in das Ziel importieren Datenbank.

(enter image description here

Unten sind die Schritte zum Kuchenlauf aufgeführt:

Hinweis :

a) Stellen Sie sicher, dass eine leere Tabelle in der Zieldatenbank vorhanden ist

b) Stellen Sie sicher, dass der Ordner Temp im Laufwerk [~ # ~] c [~ # ~] vorhanden ist

  1. Erstellen Sie eine Bat-Datei mit dem Namen Export_Data.bat Mit dem folgenden Befehl:

    bcp.exe [Source_DataBase_Name].[dbo].[TableName] OUT "C:\Temp\TableName.bcp" -S "Computer Name" -U "SQL Server UserName" -P "SQL Server Password" -n -q 
    

    pause

  2. Führen Sie diese bat-Datei aus. Infolgedessen wird eine bcp Datei im Ordner Temp generiert

  3. Erstellen Sie dann mit dem folgenden Befehl eine weitere Bat-Datei mit dem Namen Import_Data.bat:

    bcp.exe [Destination_DataBase_Name].[dbo].[TableName] IN "C:\Temp\TableName.bcp" -S "Computer Name" -U "SQL Server UserName" -P "SQL Server Password" -n -q 
    

    Pause

Und es geht los!

0
Kms