2012-11-15 30 views
1

我有一些CSV文件,我需要打開CSV文件,讀取CSV的第一行,並轉換成臨時SQL表,然後將數據加載到SQL表如下:解析CSV的第一行到SQL表使用批處理文件

閱讀CSV的線條和每行:
掰成領域創建一個臨時SQL表 插入這些字段到數據庫表

的一排我想是這樣的

此腳本現在分爲4個部分,文件初始化;文件的創建,處理和數據複製, 一切工作正常,除了上fil.sql我收到輸出

     CREATE TEMP TABLE temtab(
         firstcolumn character varying (255), 
         secondcolumn character varying (255), 
          lastcolumn character varying (255), 
          ); 
         \COPY temtab from bio.csv WITH DELIMITER ; csv HEADER 

雖然我想不逗號去年山坳

     CREATE TEMP TABLE temtab (
         firstcolumn character varying (255), 
         secondcolumn character varying (255), 
         lastcolumn character varying (255) 
          ); 
        \COPY temtab from bio.csv WITH DELIMITER ; csv HEADER 







      @echo off 
      ::setlocal enabledelayedexpansion 
      REM Assiging dir to current directory 
       SET dir=%CD% 
       REM Defining database name 
       SET dbname=**** 
       REM Defining Host name 
       SET host=**** 
       REM Defining user 
       SET user=**** 
       REM Defining Port 
     SET port=**** 
       REM SQL file where query is to be executed 
       SET sqfile=fil.sql 

      SET fi=bio.csv 
       call:fileinitialization 

       call:filecreation 

       call:proces 

        call:copydata 
      goto:eof 

     :fileinitialization 
      REM Assigning name of temporary table 
        SET tabnam=temtab 
      REM Setting delimiter to variable delim 
      SET delim=; 
     REM Declaring variable numfields to store index of variable names array 
    set numFields=0 
    echo para setted 
    set fi=bio.csv 
    SET tex=text 
    SET com=, 
       GOTO:EOF 

      :filecreation 
      REM Setting create temporary table command with table name tabnam 
      SET creat=CREATE TEMP TABLE %tabnam% 
      echo %creat% 

        GOTO:EOF 

       :proces 
       REM Executing loop for each file in current directory 
      echo %creat%>fil.sql 
     REM Read the lines of the CSV file 
     For /F "eol==" %%A in (bio.csv) Do (set "line=%%A" 


       REM check if index of array is 0 
        if !numFields! equ 0 (
         REM Fisrt line, Store in array name 
         for %%B in (!line: ^=!) do (
       echo %%B character varying (255^),>>fil.sql 

         set /A numFields+=1 
        set name[!numFields!]=%%B 
        ))) 





      GOTO:EOF 

      :copydata 
      echo \COPY %tabnam% from %fi% WITH DELIMITER %delim% csv HEADER 
      echo \COPY %tabnam% from %fi% WITH DELIMITER %delim% csv HEADER;>>fil.sql 
        GOTO:EOF 
       ::endlocal 
        Pause 
+2

你知道,你可以使用'COPY'命令或psql的'\ copy'導入平面文件到Postgres的表? –

+0

是的,我可以複製,但現場是在這裏不同,一切都是動態地完成,首先根據提交臨時表必須被創建,然後數據必須被複制 – user1622089

回答

1

雖然我不瞭解SQL表格的格式,我可以告訴你如何讀取CSV文件。下面的批處理文件讀取文件中的所有行;它首先採取從第一線(CSV報頭)字段名,並創建一個數組變量名的(消除字段名稱可能空格);然後它讀取其餘的行並將每個字段值分配給其相應的批次變量。

ProcessCSV.BAT:

@echo off 
rem General-purpose CSV file reader program 
rem Antonio Perez Ayala 

setlocal EnableDelayedExpansion 
set numFields=0 
rem Read the lines of the CSV file 
for /F "delims=" %%a in (CSVfile.csv) do (
    set "line=%%a" 
    if !numFields! equ 0 (
     rem It is the first line: break it into an array of field names (removing spaces) 
     for %%b in (!line: ^=!) do (
     set /A numFields+=1 
     set name[!numFields!]=%%b 
    ) 
    ) else (
     rem Replace spaces by Ascii-128 (to avoid split values that may have spaces) 
     set "line=!line: =Ç!" 
     rem Insert any char. at beginning of each field, and separate fields with spaces 
     set i=0 
     for %%b in (X!line:^,^= X!) do (
     set "field=%%b" 
     rem Recover spaces in this field, if any 
     set "field=!field:Ç= !" 
     rem And assign it to corresponding variable (removing first character) 
     set /A i+=1 
     for %%i in (!i!) do set "!name[%%i]!=!field:~1!" 
    ) 
     rem At this point all variables have the values of current record. 
     rem They may be accessed explicitly (ie, from example CSVfile.csv): 
     echo/ 
     echo Record of !FirstName! !LastName! 
     rem ... or implicilty via the NAME array: 
     for /L %%i in (3,1,!numFields!) do (
     for %%b in (!name[%%i]!) do echo %%b: !%%b! 
    ) 
    ) 
) 

CSVfile.csv:

First Name,Last Name,Address,Postal Code,Company,Departament,Floor,Phone,Mobile 
John,Smith,123 Fake Street,45612,SomeCo,Accounting,4,123-555-5555,123-555-5556 
Jane,Doe,123 Fake Street,,SomeCo,,4,123-555-5555,123-555-5556 

輸出:

Record of John Smith 
    Address: 123 Fake Street 
    PostalCode: 45612 
    Company: SomeCo 
    Departament: Accounting 
    Floor: 4 
    Phone: 123-555-5555 
    Mobile: 123-555-5556 

Record of Jane Doe 
    Address: 123 Fake Street 
    PostalCode: 
    Company: SomeCo 
    Departament: 
    Floor: 4 
    Phone: 123-555-5555 
    Mobile: 123-555-5556 

請注意,這個程序使用幾種先進的批量技術。我建議你得到的每一個命令你不完全理解(即?:SET /)的幫助,仔細閱讀。如果這個過程之後,你有關於這個項目的其他問題,只是張貼他們在你原來的問題編輯。

這個程序最複雜的部分是當相應的字段爲空(兩個逗號並排)時,負責將空字符串賦值給變量;如果文件沒有空字段,程序可能會更簡單一些。另外,如果某些特殊字符批處理文件中出現,這樣的程序(如大多數批量解決方案)可能給出錯誤的結果!如果需要,可以通過程序中的某些修改來管理大多數這些字符。

編輯:

for %a in (one two,three;four=five) do echo %a 
:當沒有空領域存在

@echo off 
rem CSV file reader program when no empty fields exist 
rem Antonio Perez Ayala 

setlocal EnableDelayedExpansion 
set numFields=0 
rem Read the lines of the CSV file 
for /F "delims=" %%a in (CSVfile.csv) do (
    set "line=%%a" 
    if !numFields! equ 0 (
     rem It is the first line: break it into an array of field names (removing spaces) 
     for %%b in (!line: ^=!) do (
     set /A numFields+=1 
     set name[!numFields!]=%%b 
    ) 
    ) else (
     rem Replace spaces by Ascii-128 (to avoid split values that may have spaces) 
     set "line=!line: =Ç!" 
     rem Separate fields (using comma as standard Batch separator) 
     set i=0 
     for %%b in (!line!) do (
     set "field=%%b" 
     rem Assign this field to corresponding variable, recovering spaces 
     set /A i+=1 
     for %%i in (!i!) do set "!name[%%i]!=!field:Ç= !" 
    ) 
     rem At this point all variables have the values of current record. 
     rem They may be accessed explicitly (ie, from example CSVfile.csv): 
     echo/ 
     echo Record of !FirstName! !LastName! 
     rem ... or implicilty via the NAME array: 
     for /L %%i in (3,1,!numFields!) do (
     for %%b in (!name[%%i]!) do echo %%b: !%%b! 
    ) 
    ) 
) 

請注意,在設置的標準分離器是逗號,分號和等號,除了空間改良版

上一個程序用另一個字符替換空格,並使用逗號分隔字段。但是,如果該行可能包含分號或等號,則該字段將在該位置分割,因此在這種情況下,這些字符必須在FOR之前更改爲另一個字符,並稍後以與空間相同的方式進行恢復。

編輯:修改爲新的請求(消除最後一個逗號)

消除最後一個逗號是不平凡的,雖然沒有過多複雜的都不是。我希望我的方法容易理解;它是基於SET/P命令行顯示的文本(輸入提示符),最後沒有新行;請注意,格式是SET /P =text>>out<NUL。需要<NUL部分,以便SET/P不會等待輸入;請勿在<(與>>相同)之前留出空格。但是,我認爲,這種行爲在Windows Vista中不適用於更高版本。如果該方法不爲你工作,則必須再次修改...

我也向前移動,幷包括有關仍然在你的代碼所缺少(我認爲)的部分一些言論,也就是處理幾個文件。

:proces 
REM Executing loop for each file in current directory 
REM *This may be done with a FOR loop:* 
::*for %%F in (*.csv) do (* 
    REM *The file name is given by %%F. In this case, the fileinitialization part* 
    REM *must be done here, for example:* 
    set numFields=0 
    echo %creat%>fil.sql 
    REM Read the lines of the CSV file 
    For /F "eol==" %%A in (bio.csv) Do ( 
     set "line=%%A" 
     REM check if index of array is 0 
     if !numFields! equ 0 (
      REM First line, Store in array name 
      for %%B in (!line: ^=!) do (
       REM Note that I changed the place of the ECHO command 
       set /A numFields+=1 
       set name[!numFields!]=%%B 
       if !numFields! equ 1 (
        REM First field: show it with NO comma and NO NEW LINE 
        set /P =%%B (text^)>>%sqfile%<NUL 
       ) else (
        REM Next fields: complete the comma of previous field, WITH NEW LINE 
        echo ,>>%sqfile% 
        REM ... and show this field with NO comma and NO NEW LINE (again) 
        set /P =%%B (text^)>>%sqfile%<NUL 
       ) 
      ) 
      REM Insert the new line of last field (that have NOT comma :-) 
      echo/>>%sqfile% 
     ) 
    ) 
::*)* 
GOTO:EOF 

:copydata 

我強烈建議您讓我以前的格式:用括號括起來的每個代碼塊中4的理由列,並放置在右括號打開指示的同一列中,或IF。這種格式將幫助您輕鬆定位由於大型程序中括號不匹配導致的錯誤。

安東尼

+0

@Antonio感謝ü安東尼奧,U [R輝煌,這對我的幫助很多,但還沒有完成,即使我們不知道什麼是sql表的格式,因爲sql表是從csv的第一行生成的,並且數據必須被插入,我使用你的文件進行了一些更改,並更新它們,不,我們沒有空的領域,再次感謝 – user1622089

+0

@Antonio:安東尼奧在哪裏ru ??? helpppp..made一些修改, – user1622089

+0

@ user1622089:當存在添加任何空字段修改版... – Aacini

相關問題