1

私はいくつかの csv ファイルを持っています。csv ファイルを開き、csv の最初の行を読み取って一時的な SQL テーブルに変換し、次のようにデータを SQL テーブルにロードする必要があります。

CSV の行を読み取り、各行について:
フィールドに分割する 1 つの一時的な 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
4

1 に答える 1

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 /?)についてヘルプを取得し、注意深く読むことをお勧めします。このプロセスの後で、このプログラムについてさらに質問がある場合は、元の質問の編集として投稿してください。

このプログラムの最も複雑な部分は、対応するフィールドが空の場合(2つのコンマを並べて)、変数に空の文字列を割り当てる役割を果たします。ファイルに空のフィールドがない場合、プログラムは多少単純になる可能性があります。また、このプログラム(ほとんどのバッチソリューションと同様)は、!のような特定の特別なバッチ文字がファイルに表示される場合、誤った結果をもたらす可能性があります。これらの文字のほとんどは、プログラムの特定の変更によって必要に応じて管理できます。

編集: 空のフィールドが存在しない場合の修正バージョン

@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セットの標準の区切り文字は、スペースの他に、コンマ、セミコロン、等号であることに注意してください。

for %a in (one two,three;four=five) do echo %a

以前のプログラムでは、スペースを別の文字に置き換え、コンマを使用してフィールドを区切ります。ただし、行にセミコロンまたは等号が含まれている可能性がある場合、フィールドはその時点で分割されるため、この場合、これらの文字はFORの前に別の文字に変更し、後でスペースと同じ方法で復元する必要があります。

編集: 新しいリクエストの変更(最後のコンマを削除)

最後のコンマを削除することは簡単ではありませんが、それほど複雑でもありません。私の方法が理解しやすいことを願っています。これは、テキストの表示(入力プロンプト)のSET / Pコマンドの動作に基づいており、最後に改行はありません。形式は。であることに注意してくださいSET /P =text>>out<NUL<NULSET / Pが入力を待たないようにするために、この部分が必要です。<(と同じ)の前にスペースを残さないでください>>。ただし、この動作はWindowsVista以降のバージョンでは機能しないと思います。メソッドが機能しない場合は、再度変更する必要があります...

また、先に進んで、コードにまだ欠落している部分(私は思う)、つまり、いくつかのファイルの処理についていくつかのコメントを含めます。

: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つの位置揃え列を置き、閉じ括弧を開始コマンドの同じ列(FORまたはIF)に配置します。この形式は、大規模なプログラムで括弧が一致しないために発生するエラーを簡単に見つけるのに役立ちます。

アントニオ

于 2012-11-16T04:42:12.240 に答える