2012-03-29 5 views
1

私のテーブルの1つに時間を書き込むためにSQL Server上で時計を使う必要があるので、私はちょうどGETDATE()を使うと思っていました。問題は、INSTEAD OFトリガーのためにエラーが発生していることです。別の列がID列の場合、ある列をGETDATE()に設定する方法はありますか?INSTEAD OFトリガーとアイデンティティ列を持つLinq to SQL

これは、LINQのツーSQLです:

internal void LogProcessPoint(WorkflowCreated workflowCreated, int processCode) 
{ 
    ProcessLoggingRecord processLoggingRecord = new ProcessLoggingRecord() 
    { 
     ProcessCode = processCode, 
     SubId  = workflowCreated.SubId, 
     EventTime = DateTime.Now // I don't care what this is. SQL Server will use GETDATE() instead. 
    }; 

    this.Database.Add<ProcessLoggingRecord>(processLoggingRecord); 
} 

は、これはテーブルです。 EventTimeは私がGETDATE()として持っていたいものです。私は列をnullにしたくありません。

enter image description here

そして、ここでトリガーです:

ALTER TRIGGER [Master].[ProcessLoggingEventTimeTrigger] 
    ON [Master].[ProcessLogging] 
    INSTEAD OF INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    SET IDENTITY_INSERT [Master].[ProcessLogging] ON; 

    INSERT INTO ProcessLogging (ProcessLoggingId, ProcessCode, SubId, EventTime, LastModifiedUser) 
     SELECT ProcessLoggingId, ProcessCode, SubId, GETDATE(), LastModifiedUser FROM inserted 

    SET IDENTITY_INSERT [Master].[ProcessLogging] OFF; 
END 

私が試したのバリエーションのすべてに得ることなく、この最後の試みは、このエラーを生成します。

InvalidOperationExceptionが メンバーオートシンクの失敗。挿入後に自動同期されるメンバーの場合、タイプには自動生成のIDまたは挿入後にデータベースによって変更されないキーが必要です。

エンティティからEventTimeを削除することはできますが、そのようにしたくありません。それがなくなってしまった場合は、INSERT中にNULLになり、GETDATE()が使用されます。

私は単にINSERTのEventTime列でGETDATE()を使用できますか?

注:私は二つの理由からC#のDateTime.Nowを使用したくない: 2.タイムズがマシンごとに異なることができます(別のストアドプロシージャから)これらのインサートの 1つSQL Server自体によって生成され、私のプロセスがどのくらい速く起こっているかを正確に知りたいのです。

答えて

2

ボブ、

ここでは2つの異なる問題を解決しようとしているようです。そのうちの1つは、代わりのトリガーを使用したL2Sエラーと、列のSQL Serverボックスの日付を使用した別のエラーです。 TriggersとL2Sの代わりに問題があると思います。このようにAfterトリガーを使用するアプローチを試してみるとよいでしょう。私はこれがあなたの両方の問題を解決すると思います。

ALTER TRIGGER [Master].[ProcessLoggingEventTimeTrigger] 
ON [Master].[ProcessLogging] 
AFTER INSERT 

AS 
BEGIN 
UPDATE [Master].[ProcessLogging] SET EventTime = GETDATE() WHERE ProcessLoggingId = (SELECT ProcessLoggingId FROM inserted) 
END 
+0

これは完璧に機能しました!ありがとう! –

1

EventTime列にデフォルト値(getdate())を使用してみましたか? トリガーに値を設定する必要はなく、自動的に設定されます。

明示的に値を指定しないと、デフォルト値が使用されます。

INSERT INTO ProcessLogging (ProcessLoggingId, ProcessCode, SubId, LastModifiedUser) 
    SELECT ProcessLoggingId, ProcessCode, SubId, LastModifiedUser FROM inserted 

enter image description here

+0

しかし、データがNULLの場合にのみ使用されます。 –

+0

詳細と更新された回答 – Phil

+0

これは私がやりたいことですが、問題はID列です。私は別のエラーを取得します。あなたの* exact *シナリオを試してみましょう。 –

2

defualtを使用し、トリガーを使用しないでください:

create table X 
(id int identity primary key, 
value varchar(20), 
eventdate datetime default(getdate())) 

insert into x(value) values('Try') 
insert into x(value) values('this') 

select * from X 

それははるかに良いです。

+0

デフォルトを使用することができれば、ほとんどの場合、トリガを使用することをお勧めします。 – HLGEM

0

ボブ、私はSQLサーバーでのトリガを使用しない方が良いです見

。それには多くの欠点があり、データベースのパフォーマンスの向上にはお勧めできません。 Triggers problemsの詳細については、SQL Authorityのブログを参照してください。

次の手順を使用してトリガすることなく、あなたが望むものを達成することができます

  1. 変更Eventime列がのGetDateにヌル
  2. 設定イベント時刻列デフォルト値を許可するように()。したがって、常に現在の挿入値を持ちます。
  3. LinqToSQLコードからEventTime値をDateTime.Nowに設定しないでください。これにより、SQL Serverのデフォルト値が使用されます。
関連する問題