2017-06-08 4 views
1

die Situation ist folgende:Wie Bulk-Einsatz mit einem dynamischen Wert für eine Spalte

Ich habe 200 txt-Dateien mit unterschiedlichen Namen wie 601776.txt Namen jeder Datei ist eigentlich ein ID_foo und es enthält einige Daten wie diese (2 Spalten):

04004 Albánchez 
04006 Albox 
04008 Alcóntar 
04009 Alcudia de Monteagud 
. 
. 
. 

jetzt will ich Bulk diese tXT-Dateien in einer SQL Server-Tabelle, die drei Spalte eine dieser Spalten hat, sollte der Name der txt-Datei sein. Ich benutze ein PHP-Skript, also habe ich eine Schleife gemacht, um die Dateinamen zu bekommen und was dann?

BULK INSERT Employee_Table 
    FROM '../home/601776.txt' 
    WITH ( 
     FIELDTERMINATOR ='\t', 
     ROWTERMINATOR = ''\n'' 
     ) 

Wie kann ich die dritte Spalte beim Bulk-Einfügen mit $ file_name Variable in jeder Schleife festlegen?

Denken Sie, es ist eine bessere Idee, wenn es möglich ist, die Tabelle durch Lesen der TXT-Datei Zeile für Zeile einfügen? Und wie?

Dank

+0

Wenn ich so etwas in C# getan habe, habe ich eine Methode geschrieben, um in die Datei zu gehen und die Daten, die ich brauche, in die CSV hinzuzufügen. Die Bulk_Insert (soweit ich weiß, bitte korrigieren Sie mich, wenn ich falsch liege) ist ziemlich dumm, in dem es nur die Datei und fügt ein, Sie können nicht wirklich einmischen. Also, um Ärger zu sparen, bekomme ich die Datei, wie ich es brauche, bevor ich die Massen einfüge. – Leonidas199x

+0

@ Leonidas199x das ist eine gute Option zu, aber ich möchte wissen, gibt es eine Möglichkeit, direkt zu verwenden BULK INSERT –

+0

, so dass Sie eine 3. Spalte mit dem Dateinamen haben möchten und die Massen einfügen auf 'n' Anzahl der Dateien ... im Grunde alle von ihnen in einem Verzeichnis ich vermute? – scsimon

Antwort

0

Dies ist eines der wenigen Male, dass ein Cursor tatsächlich ideal in SQL Server ist. Hier ist ein Weg. Sobald Sie die PRINT-Anweisung sehen und zufrieden sind, können Sie sie auskommentieren und die zwei Zeilen darunter auskommentieren. Ich gebe eine Logik ein, um den Dateinamen und ein verarbeitetes Datum hinzuzufügen, das normalerweise benötigt wird, aber Ihre Tabellendefinition würde diese Spalten benötigen. Es sollte die Idee vermitteln.

--------------------------------------------------------------------------------------------------------------- 
--Set some variables 
--------------------------------------------------------------------------------------------------------------- 

DECLARE @dt VARCHAR(10)               --date variable but stored as VARCHAR for formatting of file name 
DECLARE @fileLocation VARCHAR(128) = 'E:\DATA_TRANSFERS\'      --production location which is \\issqlstd01 but the xp_dirtree didn't like this 
DECLARE @sql NVARCHAR(4000)              --dynamic sql variable 
DECLARE @fileName VARCHAR(128)             --full file name variable 


--------------------------------------------------------------------------------------------------------------- 
--Get a list of all the file names in the directory 
--------------------------------------------------------------------------------------------------------------- 

IF OBJECT_ID('tempdb..#FileNames') IS NOT NULL DROP TABLE #FileNames 
CREATE TABLE #FileNames (
    id int IDENTITY(1,1) 
    ,subdirectory nvarchar(512) 
    ,depth int 
    ,isfile bit) 
INSERT #FileNames (subdirectory,depth,isfile) 
EXEC xp_dirtree @fileLocation, 1, 1 





--------------------------------------------------------------------------------------------------------------- 
--Create a cursor to fetch the file names 
--------------------------------------------------------------------------------------------------------------- 

DECLARE c CURSOR FOR 
select subdirectory from #FileNames where isfile = 1 

OPEN c 
FETCH NEXT FROM c INTO @fileName 

--------------------------------------------------------------------------------------------------------------- 
--For each file, bulk insert 
--------------------------------------------------------------------------------------------------------------- 


WHILE @@FETCH_STATUS = 0 
    BEGIN 

     SET @sql = 'BULK INSERT Employee_Table FROM '''+ @fileLocation + @fileName +''' WITH (FIELDTERMINATOR = ''\t'',KEEPNULLS,ROWTERMINATOR = ''0x0a'')' 


     --Try the bulk insert, if error is thrown log the error 
     --Also update the Table Columns which aren't a part of the original file (load date and original file name) 
     BEGIN TRY 
      PRINT(@sql) 
      --EXEC(@sql) 
      --UPDATE Employee_Table SET OrigFile = @fileName, LoadDate = GETDATE() WHERE OrigFile IS NULL 
     END TRY 
     BEGIN CATCH 
      SELECT ERROR_MESSAGE() 
     END CATCH 

     FETCH NEXT FROM c INTO @fileName 
    END 

CLOSE c 
DEALLOCATE c 

GO 
Verwandte Themen