2011-02-09 8 views
2

大規模なテキストファイルの履歴税関データをデータベースに読み込む必要がありますが、データはちょっと混乱しています。SQLを使用して異なる日付の複合エントリ

関税タイプ尺度(実際の速度及び有効日)から成る

タイプは、タイプコードと説明により定義されます。 メジャーには、レート、それに適用される地理的エリア、レート、開始日、終了日が含まれます。

問題は、1つのエントリに複合される必要がある異なる有効日付を持つ同じ料金表に対して複数のエントリがあることです。

(のTypeCode、エリア、レート、開始日、終了日、説明)
1:01021000#GEN #FREE#20050101#20061231#純血繁殖ANIMALS#

テキストファイルには、次のようになります 2:01021000#GEN #FREE#20070101#20071231#純血繁殖動物#
3:01021000#GEN #FREE#20080101#99999999#純血繁殖動物#
4:01029000#GEN位00000040.000%位20050101#20061231#OTHER#
5:01029000#GEN#00000040.000%#20070101#20071231#OTHER#
6:01029000#GEN#00000030.000%#20080101#20091231#OTHER#
7:この例では01029000#EU#00000030.000%の#20070101#20071231#OTHER#

  • 1、2第 STARTDATEと最後ENDDATE (01021000#GEN #FREE #20050101#99999999#純血繁殖動物#)
  • 4、に配合される5人のニーズと、ワン尺度に を配合する3人のニーズone fとの測定IRST STARTDATE と最後ENDDATE(01029000#GEN #00000040.000%#20050101#20071231#OTHER#)それが異なるから あるため 異なる速度
  • 7は、別個に滞在しなければならない持っているので
  • 6は、別個に滞在しなければなりません地理的エリア

私はc#とSQLコンパクトエディションを使用しています。私はそれが主に動作しているが、それは非常に遅いです...私のインテルi3のラップトップ(66000エントリ)で約40分かかる今より効率的な方法がある必要があります

私は書いた私のステップとコンパウンディングパートのコードが与えられました。日付が後に続くかどうかを確認する必要があります。

ステップ:
トークン
に行は次のように測定テーブルに値を挿入しタイプテーブルに
をユニークするTypeCodeとその説明を挿入行
分割によってテキストファイルの行を読みますコード:

// check to see if a measure with the same typecode, area and rate has already been inserted 
String select = string.Format("SELECT TypeCode FROM Measure WHERE TypeCode = '{0}' AND AreaCode = '{1}' AND Rate = '{2}'", tokens[1], tokens[3], tokens[4]);//string.Format("SELECT TypeCode FROM Measure WHERE TypeCode = '{0}'", tokens[1]); 
SqlCeDataAdapter adapter = new SqlCeDataAdapter(select, con); 
DataTable table = new DataTable(); // Use DataAdapter to fill DataTable 
adapter.Fill(table); 

// if there are no similar records insert this one 
if (table.Rows.Count <= 0) 
{ 
    string insert = "INSERT INTO Measure VALUES (@TypeCode, @UOM, @AreaCode, @Rate, @StartDate, @EndDate)"; 
    SqlCeCommand com = new SqlCeCommand(insert, con); 

    com.Parameters.AddWithValue("@TypeCode", tokens[1]); 
    com.Parameters.AddWithValue("@UOM", tokens[2]); 
    com.Parameters.AddWithValue("@AreaCode", tokens[3]); 
    com.Parameters.AddWithValue("@Rate", tokens[4]); 
    com.Parameters.AddWithValue("@StartDate", tokens[5]); 
    com.Parameters.AddWithValue("@EndDate", tokens[6]); 

    com.ExecuteNonQuery(); 
} 
else 
{ 
    // update the current record with the new enddate 
    string update = "UPDATE Measure SET EndDate = @EndDate WHERE TypeCode = @TypeCode AND AreaCode = @AreaCode AND Rate = @Rate"; 
    SqlCeCommand com = new SqlCeCommand(update, con); 

    com.Parameters.AddWithValue("@EndDate", tokens[6]); 
    com.Parameters.AddWithValue("@TypeCode", tokens[1]); 
    com.Parameters.AddWithValue("@AreaCode", tokens[3]); 
    com.Parameters.AddWithValue("@Rate", tokens[4]); 

    com.ExecuteNonQuery(); 
} 

ご意見やご感想をお寄せください。

答えて

0

SQL Server 2008 CEを使用している場合は、MERGEステートメントを使用してテーブルを1回だけ実行できます(http://blog.sqlauthority.com/2008/08/28/sql-server-2008- insert-to-merge-statement-one-statement for-insert-update-delete /)を使用します。 TypeCode、AreaCode、およびRateにMeasuresのインデックスを作成して、処理速度を上げることもできます。

+0

うわー、ありがとう、インデックスが大きな違いを作った! 40分から約2分まで! – Neil

0

これはC#ではなくSQL側で扱うものです。もしあれば、PoppaVeinが指摘するように

INSERT INTO PermanentTable (TypeCode, Area, Rate, StartDate, EndDate, Description) 
SELECT 
    TypeCode, Area, Rate, MIN(StartDate), MAX(EndDate), MIN(Description) 
FROM 
    TempLoad 
GROUP BY 
    TypeCode, Area, Rate 

:あなたは(のTypeCode、エリア、レート、開始日、終了日、説明)を得た分野では、このような概要を照会し、一時テーブルにすべてのデータをインポート既存のデータを更新する必要がある場合は、代わりにMERGEが必要です。ああ、ちょうどインデックスを超えて、{TypeCode、AreaCode、Rate}がパーマネントテーブルのプライマリキーであるように思えます。これを行うと、処理速度がさらに向上し、重複したデータをインポートしなくなります。

Descriptionの変更があなたの永久テーブルに新しい行を作成することを保証するかどうかを指定したとは思いません。私はそれはしないと仮定しています。

私がちょうど与えた質問には大きな制限があります:レートが適用される連続していない期間がある場合、これはギャップを「ペーパーオーバー」します。それが可能であれば、より複雑なクエリが必要な場合にお手伝いします。実際には、そのトピック(不連続な日付範囲をマージする)がSOで頻繁にポップアップするので、あなたはおそらく適切なソリューションをかなり簡単に見つけることができます。

関連する問題