DateCreated столбец в сервере Sql?
Есть ли особый способ объявить столбец DateCreated в таблице MS Sql Server, чтобы он автоматически заполнял его соответствующей отметкой времени при создании?
Или... я должен предоставить дату и время при выполнении запроса вручную?
4 ответа
Значения по умолчанию страдают от двух основных недостатков.
- если оператор вставки указывает значение для столбца, значение по умолчанию не используется.
- столбец может быть обновлен в любое время.
Это означает, что вы не можете быть уверены, что значения не были изменены вне вашего контроля.
Если вы хотите истинную целостность данных (чтобы вы были уверены, что дата в строке - это дата создания), вам нужно использовать триггеры.
Триггер вставки для установки столбца на текущую дату и триггер обновления для предотвращения изменения этого столбца (или, точнее, установки его текущего значения) - это способ реализации столбца DateCreated.
Триггер вставки и обновления для установки столбца на текущую дату - это способ реализации столбца DateModified.
(отредактируйте от пользователя Габриэля - вот моя попытка реализовать это, как описано - я не уверен на 100%, что это правильно, но я надеюсь, что ОП рассматривает это...):
CREATE TRIGGER [dbo].[tr_Affiliate_IU]
ON [dbo].[Affiliate]
AFTER INSERT, UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Get the current date.
DECLARE @getDate DATETIME = GETDATE()
-- Set the initial values of date_created and date_modified.
UPDATE
dbo.Affiliate
SET
date_created = @getDate
FROM
dbo.Affiliate A
INNER JOIN INSERTED I ON A.id = I.id
LEFT OUTER JOIN DELETED D ON I.id = D.id
WHERE
D.id IS NULL
-- Ensure the value of date_created does never changes.
-- Update the value of date_modified to the current date.
UPDATE
dbo.Affiliate
SET
date_created = D.date_created
,date_modified = @getDate
FROM
dbo.Affiliate A
INNER JOIN INSERTED I ON A.id = I.id
INNER JOIN DELETED D ON I.id = D.id
END
Вы можете установить значение по умолчанию для столбца в "getdate()"
У нас есть DEFAULT для CreatedDate и мы не применяем триггеры
Есть моменты, когда мы хотим установить дату явно - например, если мы импортируем данные из какого-то другого источника.
Существует риск того, что ошибка приложения может привести к путанице с CreateDate или недовольным администратором баз данных в этом отношении (у нас нет не администраторов баз данных, подключающихся напрямую к нашим базам данных)
Я полагаю, вы могли бы установить разрешения уровня столбца на CreateDate.
На полпути может быть, что INSERT TRIGGER создаст строку в таблице 1:1, чтобы столбец находился за пределами основной таблицы. Вторая таблица может иметь разрешения SELECT, где основная таблица имеет разрешения UPDATE и, следовательно, не нуждается в триггере UPDATE для предотвращения изменений в CreateDate, что устранит некоторый "вес" при обычном обновлении строк.
Я полагаю, у вас может быть триггер UPDATE/DELETE на второй таблице, чтобы предотвратить изменение (которое никогда не будет выполнено в нормальных условиях, поэтому "легковесное")
Немного неприятно иметь дополнительную таблицу, хотя... может быть одна таблица для всех CreateDates - TableName, PK, CreateDate. Большинство архитекторов баз данных будут ненавидеть это, хотя...
Конечно, есть.
Вот пример в действии для вас.
Create table #TableName
(
ID INT IDENTITY(1,1) PRIMARY KEY,
CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
SomeDate VARCHAR(100)
)
INSERT INTO #TableName (SomeDate)
SELECT 'Some data one' UNION ALL SELECT 'some data two'
SELECT * FROM #TableName
DROP TABLE #TableName
Установка значения по умолчанию недостаточно, вам следует добавить триггер, чтобы предотвратить обновление:
CREATE TRIGGER UpdateRecord ON my_table
AFTER UPDATE AS UPDATE my_table
SET [CreatedDate] = ((SELECT TOP 1 [CreatedDate] FROM Deleted d where d.[id]=[id]))