2012-04-10 8 views
0

SQL Server 2008ではトリガーを扱っていませんでした。テーブルのランク付けを実装するためのトリガーの作成

私はゲームアプリケーションを持っています、私は質問の数を追跡しています&質問の合計が正しく答えました。また、各質問の平均時間も保存しています。

ここでは、正しい回答の割合に応じてランクを記録したいと思います。ネクタイがある場合は、時間を確認します。私はトリガーを使用してこれをすべて行う必要があります。

id | playerID | CompetitionID | NoOfCOrrectANswers | NoOfPlayedQuestions | TimeTaken 
----------------------------------------------------------------------------------------- 
    1  3    203    4      8     8.4 
    2  56   203    9      18     13 
    3  67   203    16      45     15 

何か助けていただければ幸いです。前もって感謝します。

+4

開始のトリガを作成しなければならないと感じた場合彼らがどのように働いているかを理解し、より複雑なものに組み込みます。あなたが予想通りに動作しないトリガーを持っている場合、ここにコードを掲示すれば人々が助けることができます – Brian

+0

ちょっと考えました。なぜ、プレイヤー1が2秒で質問1に答えたかのような生データを追跡するだけではないからです。次に、平均などを処理するテーブルの上にビューを作成します。ビュー内でSQL 2008ランク関数を使用することもできます。トリガーは、テーブルが頻繁に叩かれたり激しく叩かれたりするときに、パフォーマンスを低下させる可能性があります。ビューを使用すると、必要なときにのみ必要な値を計算することができます。 – Namphibian

+0

ソーステーブルの定義、つまりプレイヤーがどのように回答したか、ターゲットテーブル定義のデータを含むテーブルを追加できれば、もう少しお手伝いできるでしょう。テーブルの定義がなければ、私は役に立たないだろう。 – Namphibian

答えて

2

更新の回数が多くなるため、この道を踏むべきではないでしょう。競合の結果を示すクエリにrow_number()またはrank()機能を追加することができます。言われていること

、あなたは絶対に、テーブル内の情報をランキング持続列

alter table ATable add PlayerRank int 

を追加し、簡単なトリガを作成することにより、ATABLE

create trigger RankingTrigger on ATable 
after insert, update, delete 
as 
-- We don't want queries in a trigger to mess up with "Rows affected" 
    set nocount on 
-- If any of the following columns are mentioned in a query 
-- Always true for insert and delete, but we will save updates 
-- if we skip processing when columns participating in ranking 
-- are not changed 
    If update (NoOfCOrrectANswers) 
     OR update(NoOfPlayedQuestions) 
     OR update(TimeTaken) 
    begin 
     -- CTE that returns primary key and rank by competition. 
     -- I've changed your condition (percent of correct answers) 
     -- As it would rank players with one correct answer over those 
     -- who answered 100 questions and got only one wrong. If you 
     -- want to change it, replace NoOfCOrrectANswers with 
     -- NoOfCOrrectANswers/NoOfPlayedQuestions 
     ; with theRank as (
     select ID, row_number() over (partition by CompetitionID 
             order by NoOfCOrrectANswers DESC, 
               TimeTaken DESC) rn 
      from ATable 
     -- Only changed competitions 
     where CompetitionID in 
     -- Inserted table is available in trigger and OUTPUT clause 
     -- of insert, update, delete statements. 
     -- It contains newly added/changed rows 
     -- We are using it here to filter only changed competitions 
     -- Similary, Deleted table hold a copy of removed rows for delete 
     -- and old values for update 
     (
      select CompetitionID 
       from Inserted 
      union 
      select CompetitionID 
       from Deleted 
     ) 
    ) 
     update ATable 
     -- Update to rank from theRank CTE 
     set PlayerRank = theRank.rn 
     from ATable 
     -- All records participation in affected competitions 
      inner join theRank 
      on ATable.ID = theRank.ID 
     -- Only change if really changed 
     -- This part is very likely not needed. I have never tested 
     -- to see if it affects performance 
      and isnull(ATable.PlayerRank, 0) <> theRank.rn 
    end 
+0

ビューでのCTEはおそらくパフォーマンスキラーのほうがはるかに少ないでしょうから、トリガーはおそらく行く方法ではないと私は同意します。ああ、あなたの答えの中で - 挿入されたテーブルはトリガーでのみ利用可能です。 OUTPUT句を使用すると、2005年以降にUPDATE、INSERTおよびDELETE文で挿入および削除された表にアクセスできます。私は出力節がこれらの隠されたSQL宝石の1つであることを発見しました。 – Namphibian

+0

@親生類このミスを指摘していただきありがとうございます。それは私の心を崩した。 –

関連する問題