2012-04-12 4 views
1

私は、特定のログから自動的にデータを取得するいくつかのテーブルを持っています。例のために、私のテーブルが2つの列から構成さ言うことができます:自動内部リレーショナルテーブルの更新

Country | someData 
--------|--------- 
USA  | 123 
Canada | 4545 
Mexico | 4363 
USA  | 3434 
... 

それは国のために別のテーブルに外部キーを使用することは理にかなっていますが、残念ながら今私は、国の列に道を繰り返しの多くを持っていますそのデータをテーブルにアップロードしても、私はそれを達成できません。データを挿入するプログラムは国の文字列を挿入し、それを変更することはできません(INSERT INTOテーブルのVALUES( 'USA'、3232)など)

テーブルが自動的に維持される方法があるのでしょうか同じ文字列を複数回は格納しないような関係のようなものです。

ありがとうございました

+0

私は実際にこれをやったことがないので、私は答えとして、それを主張するが、INSERTトリガーの代わりにチェックアウトするつもりはない - 私はあなたが上にあなたのビューを作成することができると思いますあなたのプログラムを挿入して、トリガーが実際のテーブルに外部キーを置くようにすることができます... http://msdn.microsoft.com/en-us/library/ms175521(v=sql.105).aspx –

答えて

-1

私はこの質問を理解していません。 1つの国のテーブルを持つことができ、テキスト表現をキーとして使用できます。ID番号(int、bigintなど)である必要はありません。この表には、各国のインスタンスが1つずつあります(米国、カナダ、メキシコ)。

あなたの関係には、someDataを格納する別のテーブルがあります。このテーブルには、米国のように複数のエントリを入れることができます。メリットは、あなたの国のテーブルがオブジェクト(この場合は国)についてもっと多くの列を持つことができることです。

+0

downvotedでコメントはありません...まあ? – JonH

+0

私はあなたの意見を理解していますが、データをアップロードするプログラムは非常に愚かであり、ログに表示されるようにエントリを挿入するだけなので、INSERT INTOテーブルVALUES( 'USA'、3232)の範囲で常に何かを行います。 私はその動作を変更できません。また、記録のために、私はあなたを落胆した人ではありません。 – Horatiu

+0

Horatu - これは実装の詳細です。挿入後のプロセスは 'DISTINCT ... FROM SELECT ... 'になります。'を使用してプライマリキー(片面)テーブルに挿入します。それは本当に簡単です。メインテーブルには各国のインスタンスが1つしかありません。そのため、最初に送信されるログファイルは、ログ(多くのサイドテーブル)テーブルに挿入されます。プログラムが完了したら、プログラムはログテーブルからDISTINCTの国を選択して片方のテーブルに挿入し、それらがまだ存在していないかどうかを確認することができます。 INSERT INTO OneSideTable ... – JonH

0

INSERT TRIGGERで作業します。データが挿入され

シナリオA)

表3列

CountryID INT NULL, 
Country VARCHAR(50) NULL, 
SomeData VARCHAR(MAX) NOT NULL 

アップローダを有する行うINSERT INTO MyTable(Country, SameData) VALUES(...)

あなたINSERTトリガは行ごとに

  • からinsertedテーブル内を有します
  • と別の(参照)テーブル
  • UPDATESET CountryIDにCountryID(外部キー)と一致見つける 一致する外部キー空間を

シナリオB)

2つの表

を洗浄する
  • UPDATESET Country = NULL

    アップローダーの表

    表内

    行ごと
    • から
      Country VARCHAR(50) NOT NULL, 
      SomeData VARCHAR(MAX) NOT NULL 
      

      ターゲット表

      CountryID INT NOT NULL, 
      SomeData VARCHAR(MAX) 
      

      あなたのINSERTトリガーた

    • また

    マッチした外部キ​​ーを使用してターゲット表にそれを書き換える

  • 上記のシナリオをINSTEAD OF INSERT TRIGGERと試してみてください(古典的なAFTER INSERT TRIGGERと比較して)、Country列にはDBに書き込まれていないので、その場でCountryIDに "変換"されます。シナリオBでは、アップローダーのテーブルが実際にビューになることがあります(アップローダーがビューに挿入され、挿入トリガーの代わりに作業が行われます)。以下の例を参照してください:http://msdn.microsoft.com/en-us/library/ms175089.aspx

  • 0

    これは私が今学んだベストプラクティスに従うことを保証することはできませんが、時々私の必要性が浮かび上がり、私はこれを学びたいと思っています。私はトリガーの代わりにあなたの質問に答えると思います。

    create table Country (
        id int primary key not null identity(1,1) 
        ,name varchar(10) 
    ) 
    go 
    
    create table Item (
        id int primary key not null identity(1,1) 
        ,country_id int references Country(id) 
        ,data varchar(100) 
    ) 
    go 
    
    create view ItemView as 
    select C.name, I.data 
    from Item I inner join Country C on I.country_id = C.id 
    go 
    
    create trigger tr_Item_IOI on ItemView 
    instead of insert as begin 
    
        set nocount on 
    
         -- add the country if it does not exist 
        if(not exists (select C.id from Country C inner join inserted I on C.name = I.name)) 
         insert into Country select distinct name from inserted 
    
         -- insert an item using the country id for the inserted country name 
        insert into Item (country_id, data) 
        select C.id, I.data 
        from Country C inner join inserted I on C.name = I.name 
    
    end 
    go 
    
    insert into ItemView values 
        ('USA', '123') 
        ,('Canada', '4545') 
        ,('Mexico', '4363') 
        ,('USA', '3434') 
    go 
    
    select * from ItemView 
    select * from Country 
    select * from Item 
    

    enter image description here