2012-03-29 2 views
1

Мне нужно использовать часы на моем SQL Server, чтобы написать время для одной из моих таблиц, поэтому я подумал, что просто использую GETDATE(). Проблема в том, что я получаю сообщение об ошибке из-за моего триггера INSTEAD OF. Есть ли способ установить один столбец в GETDATE(), когда другой столбец является столбцом идентификации?Linq to SQL с триггером INSTEAD OF и столбец Identity

Это 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(). Я не хочу, чтобы столбец был нулевым.

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 недостаточность Член AutoSync , Для того, чтобы члены AutoSynced после вставки, тип должен либо иметь автогенерируемый идентификатор, либо ключ, который не был изменен базой данных после вставки.

Я могу удалить EventTime из своего объекта, но я не хочу этого делать. Если бы оно исчезло, тогда это будет NULL во время INSERT и GETDATE().

Есть ли способ, которым я могу просто использовать GETDATE() в столбце EventTime для INSERT?

Примечание: Я не хочу использовать C# 's DateTime.Now по двум причинам: 1. Один из этих вставок генерируется сам SQL Server (из другой хранимой процедуры) 2. Времена могут быть разными на разных машинах, и я хотел бы точно знать, как быстро происходят мои процессы.

ответ

2

Боб,

Кажется, вы пытаетесь решить две различные проблемы здесь. Один из них связан с ошибкой L2S вместо триггера, а другой - с использованием даты в поле SQL Server для вашего столбца. Я думаю, что у вас могут быть проблемы с вместо триггеров и 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

Вы пытались использовать значение по умолчанию (getdate()) для Column EventTime? Вам тогда не нужно было бы устанавливать значение в триггере, оно будет установлено автоматически.

Значение по умолчанию используется, когда вы явно не указываете значение, например.

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

enter image description here

+0

Но это будет использоваться, только если данные были NULL, не так ли? –

+0

Обновленный ответ с подробностями – Phil

+0

Вот что я хотел сделать, но проблема в столбце ID. Я получаю разные ошибки. Позвольте мне попробовать ваш * точный * сценарий. –

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

Если вы можете использовать default, почти всегда предпочтительнее использовать триггер. – HLGEM

0

Боб,

Я вижу, что лучше не использовать триггеры в сервере SQL; он имеет много недостатков и не рекомендуется для повышения производительности базы данных. Пожалуйста, просмотрите блог SQL Authority для получения дополнительной информации о Triggers problems.

Вы можете добиться того, что вы хотите без триггеров, используя следующие шаги:

  1. Изменить Eventime колонку, чтобы нулевой
  2. Set Eventtime столбец Значение по умолчанию для GetDate(). Поэтому он всегда будет иметь текущее значение вставки.
  3. Не устанавливайте значение Eventtime в DateTime.Now из вашего кода LinqToSQL, поэтому оно примет значение по умолчанию в SQL Server.
Смежные вопросы