2012-03-29 7 views
1

Ich muss die Uhr auf meinem SQL Server verwenden, um eine Zeit in eine meiner Tabellen zu schreiben, also dachte ich, ich würde nur GETDATE() verwenden. Das Problem ist, dass ich wegen meines INSTEAD OF-Triggers einen Fehler bekomme. Gibt es eine Möglichkeit, eine Spalte auf GETDATE() zu setzen, wenn eine andere Spalte eine Identitätsspalte ist?Linq to SQL mit INSTEAD OF Trigger und einer Identitätsspalte

Dies ist der Linq-to-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); 
} 

Das ist der Tisch. EventTime ist, was ich als GETDATE() haben möchte. Ich möchte nicht, dass die Spalte null ist.

enter image description here

Und hier ist der Auslöser:

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 

Ohne in alle Variationen immer ich versucht habe, dieser letzte Versuch erzeugt diesen Fehler:

InvalidOperationException Mitglied AutoSync Scheitern . Damit Elemente nach dem Einfügen automatisch synchronisiert werden, muss der Typ entweder eine automatisch generierte Identität oder einen Schlüssel aufweisen, der nach dem Einfügen von der Datenbank nicht geändert wird.

Ich könnte EventTime aus meiner Entität entfernen, aber ich möchte das nicht tun. Wenn es jedoch weg wäre, wäre es NULL während der INSERT und GETDATE() würde verwendet werden.

Gibt es eine Möglichkeit, dass ich einfach GETDATE() in der Spalte EventTime für INSERTs verwenden kann?

Anmerkung: Ich möchte nicht, C# 's DateTime.Now aus zwei Gründen verwenden: 1. Einer dieser Einsätze von SQL Server selbst erzeugt wird (von einem anderen Stored Procedure) 2. Mal unterschiedlich auf verschiedenen Maschinen sein können, und ich möchte genau wissen, wie schnell meine Prozesse ablaufen.

Antwort

2

Bob,

Es scheint, dass Sie versuchen, zwei hier verschiedene Probleme zu lösen. Einer davon hat mit einem L2S-Fehler zu tun, der mit einem Trigger des Typs "Inherent Of" verknüpft ist, und einer, bei dem das Datum auf dem SQL Server-Feld für Ihre Spalte verwendet wird. Ich denke du könntest Probleme mit Triggern und L2S haben. Vielleicht möchten Sie einen Ansatz ausprobieren, bei dem ein After-Trigger verwendet wird. Ich denke, das wird beide Probleme lösen.

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

Das hat perfekt funktioniert! Vielen Dank! –

1

Haben Sie versucht, einen Standardwert von (getdate()) für die EventTime-Spalte zu verwenden? Sie müssten dann nicht den Wert im Trigger setzen, er würde automatisch gesetzt werden.

Ein Standardwert wird verwendet, wenn Sie nicht explizit einen Wert angeben, z.

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

enter image description here

+0

Aber das würde nur verwendet werden, wenn die Daten NULL waren, oder? –

+0

Aktualisierte Antwort mit Details – Phil

+0

Das war, was ich tun wollte, aber das Problem ist die ID-Spalte. Ich bekomme verschiedene Fehler. Lass mich dein * exact * Szenario ausprobieren. –

2

keinen Trigger Verwenden Sie, verwenden Sie einen 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 

Es ist viel besser.

+0

Wenn Sie einen Standard verwenden können, ist es fast immer vorzuziehen, einen Trigger zu verwenden. – HLGEM

0

Bob,

Ich sehe es besser ist, keine Trigger in SQL Server verwenden; Es hat viele Nachteile und wird nicht für Verbesserungen der Datenbankleistung empfohlen. Weitere Informationen zum Triggers problems finden Sie im SQL Authority-Blog.

können Sie erreichen, was Sie ohne Trigger wollen mit den folgenden Schritten:

  1. ändern Even Spalte null
  2. Set event Spalte Standardwert zu GetDate() zu ermöglichen. Es hat also immer den aktuellen Einfügewert.
  3. Setzen Sie den Eventtime-Wert nicht auf DateTime.Now aus Ihrem LinqToSQL-Code, damit er den Standardwert im SQL Server annimmt.