2016-06-20 20 views
1

.csvファイルには57列あり、一部の値は空です。たとえば、,Jane,Doe,,35です。たとえば、コンマの前の最初の値がデータベースにインポートされるたびに増分する自動IDキーの場合を考えてみましょう。問題は、空の値がインポートされないため、エラーが発生することです。ここで私が理解しているのは、SQLデータベースは空の値を読み取ることができないので、値がJane,Doe,35のように移動するため、Janeの値はIDになります。別の懸念は、.csvファイルの列がテーブルと一致しないことです。たとえば、テーブルはIDの列を持ち、.csvのファイルはNameの列で始まります。特定の列からデータベースにインポートする方法はありますか?CSVファイルをSQL Serverデータベースにインポートする

注:これは1つの表にのみ記載されています。 質問:.csvファイルの列と一致する別のテーブルを作成し、それを列ID(この例では)のテーブルと結合すると、より望ましいでしょうか?

私のコード今のところ:上記のコードの場合

 DataTable dt = new DataTable(); 

     dt.Columns.AddRange(new DataColumn[54] { new DataColumn("Delay_Code"), and so on... }); 

     string csvData = File.ReadAllText(e.FullPath); 
     foreach (string row in csvData.Split('\n')) 
     { 
      if (!string.IsNullOrEmpty(row)) 
      { 
       dt.Rows.Add(); 
       int i = 0; 
       foreach (string cell in row.Split(',')) 
       { 
        dt.Rows[dt.Rows.Count - 1][i] = cell; 
        i++; 
       } 
      } 
     } 

     string consString = @"Data Source="blahblah"; 
     using (SqlConnection con = new SqlConnection(consString)) 
     { 
      using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con)) 
      { 
       //Set the database table name 
       sqlBulkCopy.DestinationTableName = "owner.Table"; 
       con.Open(); 
       sqlBulkCopy.WriteToServer(dt); 
       con.Close(); 
      } 
     } 

、私は.csvファイルの列に一致する別のテーブルを作成しました。もともと、テーブルには、.csvファイルの列の前に3つの先行列があります。

これにはどのような方法が最適ですか?

答えて

1

ご質問は、いくつかの観点から広すぎるように見えるかもしれませんが、私はそれを理解し、私はあなたがインスピレーションとして使用することができます私のために働いた、やや広義の(ユニバーサル)アプローチを共有しています:

  1. 書き込みAまた、二重引用符文字があった場合、それはスペースや改行文字を含む任意のcharctersを受け入れることができますので、

    Value1, Value2, "Value 3", "Value ""4""", "Value 
    5",, Value 7, "Value,8" 
    
    • のようなCSVの列を扱うことができる高品質のCSVリーダー、その他の引用符が(のように記述)と、これは別のソロの引用でのみ停止します("
    • は、セパレータが,;またはタブ文字は、小数点以下の数字が.または,などが、通常生産相手方であることに注意してくださいとしてカンマを含めることができることができることを調製することCSV形式に適合する必要があるかもしれません。
    • これは有限状態マシンを使用するのが最も簡単な方法です.50 MB /秒のような軽量かつ高速です。
  2. [オプション]論理的なステップは、固定配線されたものの代わりに設定可能なインポート定義を持つことです。

    { ExternalOrders = "Data From External Orders in CSV", 
        CsvFormat = { CsvHasHeaderRow = true, 
          CsvFieldSeparator = ",", 
          DecimalSeparator = ".", 
          DateFormat = "yyyy-MM-dd", 
          DateTimeFormat = "yyyy-MM-dd hh:mm:ss", 
          TimeFormat = "hh:mm:ss" }, 
        ColumnMap = { 
         Column1 = { SourceColumnName = "OrderID", 
            SourceColumnType = "nvarchar(50)" 
            StagingColumn = 1 }, 
         Column2 = { SourceColumnName = "OrderDate", 
            SourceColumnType = "date" 
            StagingColumn = 2 }, 
         ColumnAmount = { SourceColumnPosition = 5, 
            SourceColumnType = "decimal(18,6)" 
            StagingColumn = 3 } 
         }, 
    StagingImportSql = "INSERT INTO Orders (Number, OrdDate, Amount) 
             SELECT CAST(c1 AS navarchar(50), 
               CAST(c2 AS date), 
               CAST(c3 AS money) 
              FROM StagingTable 
              WHERE ImportID = {{ImportIDToken}};" 
    } 
    
    • これはどこに、テキストコンフィギュレーションファイルに、データベース内に存在することができます。私は3つのデータベーステーブルにそれを持っている(ImportAction、CsvFormat、ColumnMapping)
  3. ID int identity(1,1) 
    ImportID int 
    CsvRowNumber int 
    c1 sqlvariant 
    c2 sqlvariant 
    c3 sqlvariant 
    ... 
    c64 sqlvariant 
    
  4. 列を使用してSQLデータベース内のステージング表を持っているから形式とCSVのインポートを呼び出し、エンジンを(作成します)を使用して、コンフィグレーションされたColumnMapに従ってステージングテーブルを満たします。ステージングテーブルにも追加の列があります(例: ImportIDまたはCsvRecordNumberインポート中にエンジンによって自動入力されます。 1つのレコードをステージングテーブルに追加するための各CSVのSQL INSERTステートメントを発行します。すべてが完了したら、StagingImportSqlを起動して、SQLコマンドのトークン{{ImportIDToken}}を実際のインポート番号に置き換えてください。

  5. あなたは、例えば、インポートした直後に、それを削除しない場合、オプションで、ステージング表の

    • パージを実装することができます見ると

をインポートし、実行することができます -

  • は日
  • ユーザー制限の与えられた数よりも古いではない輸入を保つ輸入AND/OR

  • の一定数を維持します

    私は特定のコードを共有していません。私の場合、それはであり、おそらく6000 lです多くのクラスでines。私はアイデアを共有しています。パースの


    注:

    • あなたのCSVリーダーがテーブル全体を返す文字列
      • のDataTableのを返させ、大きなCSVのために良いではありませんが、最大500メガバイト(さんが言わせて)それは、PAへInteger.Parse()よう
    • 使用方法、Decimal.Parse()Double.Parse()問題ないはずです列のデータ型に応じて単純な値をrseします。パースする前に、カスタム小数点区切り文字または標準小数点区切り文字を置き換えることができます。
    • 日付と時刻の
    • は、データ型の内部処理のために
    • DateTime.ParseExact()を使用し、列挙型System.Data.SqlDbTypeはあなたの友達です
  • 関連する問題