Nach vielen Recherchen scheint es offensichtlich zu sein, dass es keine Möglichkeit gibt, die Zeilenreihenfolge mit dem Befehl "Bulk Insert", wie er von Microsoft angeboten wird, beizubehalten. Sie müssen entweder selbst eine ID-Spalte direkt in die Importdatei einfügen, eine Shell oder ein anderes externes Skript verwenden, oder Sie verzichten darauf. Es scheint, dass dies eine notwendige (und einfache) Funktion für Microsoft wäre, aber nach mehr als einem Jahrzehnt, in dem Microsoft nichts getan hat, wird das nicht passieren.
Ich musste jedoch die tatsächliche Reihenfolge der Datensätze in der Importdatei nach dem Import beibehalten, da die höheren Datensätze die niedrigeren verdrängen würden, wenn eine bestimmte Spalte denselben Wert hätte.
Also habe ich einen anderen Weg gewählt. Meine Zwänge waren:
- Ich konnte die Quelldatei überhaupt nicht ändern. (und einen schlechten Präzedenzfall geschaffen!)
- Ich konnte kein externes Skript verwenden. Zu kompliziert. Es musste eine einfache T-Sql-basierte Lösung sein, keine CMD-Ausführungen. Das Ganze musste in einer einzigen Prozedur ablaufen, damit es automatisiert werden konnte.
Mir gefiel die Logik der Verwendung von Powershell, um geordnete Einfügeanweisungen für jede Zeile zu erstellen, die dann in Sql ausgeführt werden. Im Wesentlichen wurde jeder Datensatz in eine Warteschlange für die individuelle Einfügung und nicht für die Masseneinfügung gestellt. Ja, es würde funktionieren, aber es wäre auch sehr langsam. Ich habe oft Dateien mit mehr als 500.000 Zeilen in ihnen. Ich brauchte etwas SCHNELLES.
So bin ich auf XML gestoßen. Bulk-Upload der Datei direkt in eine einzige XML-Variable. Dadurch würde die Reihenfolge der Datensätze beibehalten, wenn sie der XML-Datei hinzugefügt werden. Dann parsen Sie die XML-Variable und fügen die Ergebnisse in eine Tabelle ein, wobei Sie gleichzeitig eine Identitätsspalte hinzufügen.
Es wird davon ausgegangen, dass es sich bei der Importdatei um eine Standardtextdatei handelt, bei der jeder Datensatz mit einem Zeilenvorschub (Char(13)+Char(10)) endet.
Mein Ansatz besteht aus 2 Schritten:
-
Führen Sie die SQL-Anweisung IMPORT (mit OPENROWSET) aus und kapseln Sie jeden Datensatz mit XML-Tags ein. Erfassen Sie die Ergebnisse in einer XML-Variablen.
-
Parsen Sie die Variable anhand der XML-Tags in eine Tabelle und fügen Sie eine aufsteigende [ID]-Spalte hinzu.
---------------------------------
Declare @X xml;
---------------------------------
SELECT @X=Cast('<X>'+Replace([BulkColumn],Char(13)+Char(10),'</X><X>')+'</X>' as XML)
FROM OPENROWSET (BULK N'\\FileServer\ImportFolder\ImportFile_20170120.csv',SINGLE_CLOB) T
---------------------------------
SELECT [Record].[X].query('.').value('.','varchar(max)') [Record]
,ROW_NUMBER() OVER (ORDER BY (SELECT 100)) [ID]
--Into #TEMP
FROM @X.nodes('X') [Record](X);
---------------------------------
-
Die XML-Tags ersetzen jeden Zeilenvorschub.
-
Wenn die Datei mit einem Zeilenvorschub endet, wird am Ende eine Leerzeile eingefügt. Löschen Sie einfach die letzte Zeile.
Ich schrieb dies in meine Prozedur mit dynamischen Sql, so dass ich in den FileName übergeben konnte und die ID auf 1 oder 0 (für den Fall, dass es eine Kopfzeile) beginnen.
Ich konnte dies mit einer Datei mit 300K Datensätzen in etwa 5 Sekunden durchführen.
0 Stimmen
Wie können Sie angesichts der Tatsache, dass SQL-Tabellen von Natur aus ungeordnet sind, feststellen, dass die Einfügereihenfolge eine andere ist - eine automatisch inkrementierende Spalte?