0

私はこの次のシナリオを手に入れました、

COUNTRY、STATE、CITY、STREETの4つのテーブルがあり、
上記のレコードを含むExcelファイルがあります。現時点ではおそらく2000行です。

SqlBulkCopyを使用してデータを一時テーブルにインポートし、テーブルにIMPORTという名前を付けます。

そして、挿入されたレコードを取得し、国、州、都市、通りを分割して、それぞれのテーブルに挿入するIMPORTテーブルに挿入のトリガーを1つ作成しました。

このトリガーでは、いくつかの条件付きチェックを実行する必要があります。たとえば、COUNTRY名がすでに存在する場合は、COUNTRY_IDを返します。それ以外の場合は、それを挿入して新しいCOUNTRY_IDを取得します。

上記は、Excelファイルに1行しかない場合に機能します。インポート用に元のExcelを配置すると、sqlbulkcopyによってINSERTEDが複数のレコードを持つようになるため 、トリガーの次のステートメントが「INSERTEDから国を選択」に失敗することがわかりました。

テーブル構造

  • Country_ID
  • 国名

  • State_ID
  • Country_ID
  • State_Name

  • City_ID
  • State_ID
  • Country_ID
  • 市の名前

  • Street_ID
  • City_ID
  • State_ID
  • Country_ID
  • 道の名前

輸入

  • 国名
  • State_Name
  • 市の名前
  • 道の名前

それで、INSERTEDのすべてのレコードをループするループステートメントをトリガーに含めることはできますか?

または、これに最善の方法で対処する方法は?

注:彼らはすでにそれを使用しているので、私はそれらのテーブル構造とそれらの関係を制御できません。

前もって感謝します。

4

2 に答える 2

2

最初の問題は、レコードセットをループすることを最初の選択肢として考えるべきではないということです。ここにあるので、ほとんどの場合、それは間違った選択です。次の問題は、トリガーがレコードのセット全体を一度に1つずつではなく処理することです。説明から、一度に1つのレコードを処理すると仮定して記述したに違いありません。セットベースのプロセスが必要です。

トリガーに次のようなものが必要になる可能性があります。これにより、国テーブルにまだ存在しないすべての国が挿入されます(これは、country_Idが整数のID列であると想定しています)。

Insert country (country_name)
select country_name 
from inserted i
where not exists 
  (select * from country c 
   where c.country_name = i.country_name)

トリガーの代わりにストアドプロシージャを使用して、ステージングテーブルから実際のテーブルに挿入することもできます。

于 2010-11-22T14:20:54.387 に答える
1

バルクロードに使用されるテーブルのトリガーに、このような処理集約型のタスクを入れることは決してありません。そして、カーソルなどのループをトリガーに入れ始めることは決してありません-トリガーは小さく、無駄がなく、意味のあるものでなければなりません-監査テーブルなどにすばやく挿入するだけです-しかし、それは重労働をするべきではありません!

あなたがすべきことはこれです:

  • トリガーなどを使用SqlBulkLoadせずに、データをできるだけ早くステージングテーブルに取り込むために使用します
  • 次に、そのステージングテーブルに基づいて、列の値などを分割して必要な後処理を実行します。

そうでなければ、あなたはSqlBulkLoad持っている利益を完全に殺していることになります。

そして、この後処理(特定のを決定するなどCountry_IDCountryを行うために、カーソルやそれらの悪意ビットは必要ありません-UPDATEテーブルで標準のありふれたステートメントを使用するだけです-必要なのはそれだけです。

于 2010-11-22T06:12:38.743 に答える