2011-08-12 38 views
3

OF Iは、セキュリティ請負会社のために働く、と私は働いていたのPOの調整時間/回を格納し、私のデータベース内のテーブルを持っています。勤務された各日付について、財務部は仕入先の請求可能な開始日と終了日と、請求可能な開始日と終了日を入力します。ほとんどの場合、まれな状況を除いて、ベンダーとクライアントの請求可能時間は同じです。より良い代替ではなく、INSERT、UPDATEトリガー

システムの仕組みによっては、クライアントの開始時刻と終了時刻がベンダーの開始時刻と終了時刻と異なる場合を除いて、ベンダーの開始時刻と終了時刻が常に更新されます。

  • ジョブID
  • PostNumber
  • のStartTime(ベンダー開始時間)
  • ClosingTime(ベンダー開始時間)
  • ClientClosingTime
  • ClientStartTime:この情報を保存するために、私はこれらの列を持つテーブルを持っています

ベンダーとクライアントの開始時刻と終了時刻ti mesは通常互いに同期している必要があります。私はそれを処理するためにトリガーを使用すると考えました。新しい値と比較するために現在の値にアクセスする必要があるため、最初のINSERT、UPDATEトリガが最初のトリガに夢中ではなく、このテーブルにすべての挿入と更新を実行するためのトリガーが私を緊張させます。たぶんそれは私が持っている不合理な恐怖ですが、私は可能な限りトリガーから遠ざかっています。しかし、この状況では、それは最良の選択肢のように思えます。ここで

は、ロジックを明確にするべきである、私のトリガーです:

ALTER TRIGGER [dbo].[<UpdateAdjustedHours>] 
    ON [dbo].[<AdjustedHoursTable>] 
    INSTEAD OF INSERT, UPDATE 
AS 
BEGIN 

    IF (NOT EXISTS(SELECT CurrentValues.JobID FROM WorkOrderDetailAdjustment CurrentValues, Inserted NewValues WHERE CurrentValues.JobID = NewValues.JobID AND CurrentValues.PostNumber = NewValues.PostNumber)) 
    BEGIN 

     INSERT INTO WorkOrderDetailAdjustment 
      SELECT Inserted.JobID, 
        Inserted.PostNumber, 
        Inserted.StartTime, 
        Inserted.ClosingTime, 
        ISNULL(Inserted.ClientStartTime, Inserted.StartTime), 
        ISNULL(Inserted.ClientClosingTime, Inserted.ClosingTime)  
      FROM Inserted     

    END 
    ELSE BEGIN 

     UPDATE CurrentValues 
     SET  CurrentValues.StartTime = ISNULL(NewValues.StartTime, CurrentValues.StartTime), 
       CurrentValues.ClosingTime = ISNULL(NewValues.ClosingTime, CurrentValues.ClosingTime), 
       CurrentValues.ClientStartTime = (
        CASE WHEN DATEDIFF(SECOND, CurrentValues.ClientStartTime, CurrentValues.StartTime) != 0 THEN 
         ISNULL(NewValues.ClientStartTime, CurrentValues.ClientStartTime) 
        ELSE 
         NewValues.StartTime 
        END 
       ), 
       CurrentValues.ClientClosingTime = (
        CASE WHEN DATEDIFF(SECOND, CurrentValues.ClientClosingTime, CurrentValues.ClosingTime) != 0 THEN 
         ISNULL(NewValues.ClientClosingTime, CurrentValues.ClientClosingTime) 
        ELSE 
         NewValues.ClosingTime 
        END 
       ) 
     FROM WorkOrderDetailAdjustment CurrentValues, Inserted NewValues 
     WHERE CurrentValues.JobID = NewValues.JobID AND CurrentValues.PostNumber = NewValues.PostNumber 

    END 

END 

私は思ったんだけど何これを行うには良い方法があるかどうです。私はすべての提案にはオープンですが、可能であれば、これをデータベースレベルで保持したいと考えています。私はこれを行うための最良の方法を選んだと聞いていますが、なんらかの理由で私はそれを疑っています。

ありがとうございました!それはあなたの操作のために理にかなっている場合は...何ができる

答えて

2

ことの一つは、あなたのテーブルに永続化された計算列を追加することです。 (私はあなたの記述から、実際にこの値が格納されることを推測しています。そうでなければ、永続化オプションは必要ありません)。

それは合体(client_start_time、vender_start_time)のようなものである可能性があります。

また、同じことをしたビューを作成することもできます。彼らは虐待しやすいので、私は意見に夢中ではありませんが、常に悪くはありません。

Eithe rway、あなたはそれがvender_start_timeよりも、実際に異なっていたclient_start時間を入力する必要があると思います。トリガーの使用を避けることができます。

1

私は、アプリケーションのビジネスロジック層ではなく、データベースにそれを扱うお勧めします。ストアドプロシージャとトリガでのデータベースに、アプリケーションのバックエンドに -

は、私たちは、「どこでも」置かれたビジネス・ルールを持つことの苦痛の時間を経ました。私たちのアプローチを再設計し、アプリケーションを厳密な層に分割しました。開発とメンテナンスは今よりはるかにスムーズです。私の意見では、請求したデータを同期させた状態で記述したタスクは、ビジネスロジックの一部であり、そこで実装する必要があります。

関連する問題