2009-02-17 4 views
5

Есть ли специальный способ объявить столбец DateCreated в таблице MS Sql Server, чтобы он автоматически заполнил его соответствующей меткой времени при создании?DateCreated column в Sql Server?

Или .. Должен ли я предоставить дату и время, когда я делаю запрос вручную?

ответ

10

Вы можете установить значение по умолчанию столбца «GETDATE()»

+1

Помните, что это можно обойти пользователями, поскольку значение по умолчанию не учитывается при вставке фактического значения. И он также может быть обновлен пользователями. Вероятно, это достаточно хорошо, если вы можете контролировать, какой SQL запускается (и вы не можете :-), но это не безопасно. – paxdiablo

+0

Это на самом деле хорошо, потому что, если у пользователя есть конкретная дата, которую им нужно положить туда, это, вероятно, должно быть разрешено, если у вас нет правил, которые управляют иначе. – James

+0

С уважением не согласен, @James. Вы не слышали о Сарбейнсе-Оксли? :-) Если у вас есть столбец DateCreated, он должен быть установлен в дату создания строки. Если вы хотите использовать изменяемый пользователем столбец, его следует называть DateCreatedForPurposesOfFraud или что-то подобное. – paxdiablo

15

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

  • Если инструкция insert указывает значение для столбца, значение по умолчанию не используется.
  • колонка может быть обновлена ​​в любое время.

Это означает, что вы не можете быть уверены, что значения не были изменены вне вашего контроля.

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

Триггер вставки для установки столбца на текущую дату и триггер обновления, чтобы предотвратить изменения этого столбца (или, точнее, установить его текущее значение), являются способом реализации столбца 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 
+0

Если вы контролируете среду и приложение, то вы контролируете доступ к уровню данных. Эти две проблемы затем становятся неактуальными. –

+0

Действительно, вы не думаете, что кто-то может просто подключиться к СУБД с помощью драйвера JDBC? И одно из основных преимуществ n-уровня состоит в том, чтобы каждый уровень отвечал за свою целостность. Вы НИКОГДА не предполагаете, что БД защищено приложением, когда оно может защитить себя. Это требует неприятностей. – paxdiablo

+0

@Pax: Нет. Специальное соединение не может подключаться к надлежащим образом защищенным средам. Безопасность - это не единственная ответственность DMBS (она обеспечивает отправную точку), поскольку она должна быть стратегией с поддержкой сотрудничества/платформы. –

0

Наверняка есть.

Вот пример действия для вас.

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 
+0

И что происходит, когда недовольный сотрудник приходит с «UPDATE #TABLE SET CREATEDDATE = GETDATE()»? Bang, там вся ваша ценная информация о том, когда были созданы строки. – paxdiablo

+2

@Pax: Не было бы на моем торне, однако, в маловероятном случае это произошло, я бы просто реализовал наши процедуры DR и восстановил данные. Похоже, вам нужно взглянуть на вашу стратегию безопасности и моральный нрав сотрудников :-) –

+1

«Мораль», но, возможно, их мораль также должна быть проверена :-) В любом случае, профилактика всегда лучше восстановления. Это разница между временем простоя и временем простоя (ни один не лучше любой суммы). Вероятно, это больше среда, в которой я работаю, DB2 на System z, мы всегда параноики. – paxdiablo

2

Мы DEFAULT на CreatedDate и не применять с триггерами

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

Существует риск того, что ошибка приложения может связываться с CreateDate или раздраженной DBA по этому вопросу (мы не имеем, не АБД подключения непосредственно к нашей БД)

Я полагаю, вы могли бы установить столбцы уровня для CreateDate.

Поврежденный дом может состоять в том, чтобы INSERT TRIGGER создать строку в таблице 1: 1, чтобы столбец находился за пределами основной таблицы. Во второй таблице могут быть разрешения SELECT, где главная таблица имеет разрешения UPDATE и, следовательно, не требуется триггер UPDATE, чтобы предотвратить изменения в CreateDate - что приведет к удалению некоторого «веса» при нормальном обновлении строк.

Я полагаю, вы Коула есть UPDATE/DELETE триггер на второй таблицы для предотвращения изменения (которые никогда не будут выполняться в обычных условиях, так что «легкий»)

Немного боли иметь дополнительную таблицу, хотя ... может иметь одну таблицу для всех CreateDates - TableName, PK, CreateDate.Большинство архитекторов баз данных будут ненавидеть это, хотя ...