2010-04-29 5 views
1

Каков самый простой способ автоматического заполнения столбца datetime в таблице данных SQL с датой создания строки? Если это имеет значение, используйте SQL Server 2005.Столбец даты создания в таблице SQL

EDIT: Я попытался использовать GETDATE() по умолчанию и работает для запроса INSERT, но не тогда, когда TableAdapter добавляет строку.

+0

В других системах баз данных, которые могут быть 'SYSDATE' или' NOW() 'вместо' getdate() '. –

+0

Вы хотите, чтобы вы заполнили его назад? Как сегодня, вы хотите заполнить даты создания всех строк, которые когда-либо были добавлены в прошлом? Или просто двигаться вперед? – froadie

+0

Просто двигайтесь вперед в порядке. Приложение еще не развернуто. – MatsT

ответ

5
ALTER TABLE table 
ADD column NOT NULL DEFAULT (GETDATE()) 
+0

Это то, что я попытался изначально, но это не сработало, теперь я подозреваю, что VB.NET вставляет 0 вместо NULL, когда ничего не указано. – MatsT

+0

@MatsT: Null не может сигнализировать базе данных о вводе значения по умолчанию для столбца. если вы хотите указать значение по умолчанию для вставки, вы должны сделать это: «INSERT INTO» (фамилия, имя, член_домен) («lennon», «john», по умолчанию) ' –

+0

, к сожалению, вы не можете сделать:' INSERT INTO member (lastname, firstname, membership_date) значения ('lennon', 'john', coalesce (@ paramFromYourVb, default)) ' –

1

использовать функцию getdate(),

так что-то вроде: insert data1, data2, getdate() into table1

1

установить значение по умолчанию для этого:

CREATE TABLE dbo.YourTable 
    (
    columns...., 
    YourDateTime datetime NOT NULL 
    ) ON [PRIMARY] 
GO 
ALTER TABLE dbo.YourTable ADD CONSTRAINT 
    DF_YourTable_YourDateTime DEFAULT GETDATE() FOR YourDateTime 

, когда вы вставляете не перечисляют этот столбец:

INSERT INTO dbo.YourTable (columns...) VALUES (values...) 

или когда вы вставляете список, колонки, но использование DEFAULT ключевое слово:

INSERT INTO dbo.YourTable (columns...,YourDateTime) VALUES (values...,DEFAULT) 

или когда вы вставляете список этот столбец, и использовать GETDATE() или какой-либо другой DateTime:

INSERT INTO dbo.YourTable (columns...,YourDateTime) VALUES (values...,'1/1/2010 12:34:56') 
2

Вы должны создать в колонке и имеют:

  • триггер вставки (после), который устанавливает его на текущую дату (или дату/время).
  • триггер обновления (вместо этого), который не позволяет изменять столбец.

Любое решение по умолчанию не является безопасным, поскольку оно может быть обойдено либо путем специальной установки столбца при вставке или изменении столбца после этого. Решение на основе триггеров помещает элемент управления в СУБД, где он принадлежит.

+1

Почему downvote? Это правильный ответ, на мой взгляд, так как он не имеет ни одной проблемы аудита значений по умолчанию. Мне было бы интересно узнать, почему вы считаете это неправильным. – paxdiablo

+0

Я не голосовал, но пользователь не контролирует значение в приложении. –

+0

Я не понимаю вашего комментария, @Marcus. Если вы хотите, чтобы строка сохраняла дату создания, пользователь не должен иметь контроль над СУБД. – paxdiablo

0

Будьте осторожны, если вы используете репликацию. Я не знаком с внутренними деталями репликации SQL Server, но я знаю, что с некоторыми формами репликации MySQL, если вы используете NOW() в качестве значения по умолчанию или используете триггер с использованием той же функции, даты будут отличаться между базы данных издателей и подписчиков.

Если вы установили дату в приложении, тогда дата всегда точно воспроизводит. Разумеется, оговорка заключается в том, что дата или время должны быть установлены на сервере приложений (или веб-серверах), поскольку не может быть доверена дата и время на компьютере конечного пользователя.

Если вы используете репликацию, вы можете протестировать это.

1

Как вы можете видеть, у вас впереди несколько решений. Короче говоря,

  1. Вы можете написать свой метод (изнутри VBNET), который устанавливает соответствующее поле в System.DateTime.Теперь (не лучшая практика);

    Public Function InsertObject(o As Object) As Integer 
        cmd.CommandText = String.Format("INSERT INTO table_name (Id, CreationDate) VALUES (1, {0})", System.DateTime.Now) 
        Return cmd.ExecuteNonQuery() 
    End Function 
    
  2. Вы можете написать ВМЕСТО триггер INSERT и заменить CreationDate вставленный значение с GETDATE() (рекомендуемый способ);

    CREATE TRIGGER trg_bi_PersistObject 
    ON objectToPersistTable 
    INSTEAD OF INSERT AS 
        insert into objectToPersistTable (Id, CreationDate) (
         select Id, GETDATE() 
          from inserted 
        ) 
    

    (Пожалуйста, обратите внимание, что код на верхней части моей головы. Некоторые исправления могут быть необходимы для целей синтаксиса или так. Это, по крайней мере, дает основную идею.)

  3. Вы можете установить значение по умолчанию (но по некоторым причинам оно не сработало для вас).

    (см. Ответ Дэвида М или КМ для кода).

Как указано в комментарии paxdiablo о его собственном ответе, такая функция должна обрабатываться на стороне СУБД, чтобы избежать повреждения данных на стороне клиента приложения. Затем, я уверен, ваш лучший выбор может быть равен 2., создав триггер BEFORE INSERT и установив значение с помощью функции GETDATE().

Смежные вопросы