Вопрос о столбцах DateCreated и DateModified - SQL Server - PullRequest
4 голосов
/ 09 апреля 2010
CREATE TABLE Customer
(
        customerID         int identity (500,20) CONSTRAINT 
        .
        .
        dateCreated    datetime DEFAULT GetDate() NOT NULL,
        dateModified   datetime DEFAULT GetDate() NOT NULL
);

Когда я вставляю запись, dateCreated и dateModified устанавливаются на дату / время по умолчанию. Когда я обновляю / изменяю запись, dateModified и dateCreated остаются как есть? Что мне делать?

Очевидно, мне нужно, чтобы значение dateCreated оставалось тем, что было вставлено в первый раз, а dateModified продолжает изменяться, когда в полях записи происходят изменения / модификации.

Другими словами, не могли бы вы написать пример быстрого запуска? Я пока немного знаю ...

Ответы [ 7 ]

10 голосов
/ 09 апреля 2010

Возможно, вы захотите создать триггер обновления, чтобы обновить это значение для вас

Взгляните на что-то вроде

CREATE TABLE Vals(
        ID INT,
        Val VARCHAR(10),
        DateCreated DATETIME DEFAULT GetDate(),
        DateUpdated DATETIME DEFAULT GetDate()
)
GO

CREATE TRIGGER Upd ON Vals
AFTER UPDATE
AS 
UPDATE Vals
SET     DateUpdated = GetDate()
FROM    Vals INNER JOIN
        inserted ON Vals.ID = inserted.ID
Go

INSERT INTO Vals (ID, Val) SELECT 1, 'A'
SELECT *
FROM    Vals
GO

UPDATE Vals SET Val = 'B'
SELECT *
FROM    Vals
GO

DROP TABLE Vals
GO
4 голосов
/ 09 апреля 2010
UPDATE
    Customer
SET
    ... = NewValue,
    dateModified = DEFAULT
WHERE
    ...

Я бы использовал это вместо dateModified = GETDATE(), поэтому GETDATE () используется только один раз (скажем, вы хотите изменить на GETUTCDATE () в будущем)

Или триггер, если у вас есть несколько путей обновления ...?

3 голосов
/ 10 апреля 2010

Когда я вставляю запись, dateCreated и dateModified устанавливается по умолчанию дата / время. Когда я обновляю / изменяю запись, дата изменения и дата создания остается как есть? Что мне делать?

Столбец по умолчанию используется только при INSERT, а не UPDATE. По умолчанию будет использоваться команда INSERT, если вы не предоставите столбец или не введете ключевое слово DEFAULT в INSERT.

INSERT INTO Customer (col1, col2) 
VALUES (..,..)  ---get default for dateCreated & dateModified   

INSERT INTO Customer (col1, col2,dateCreated) 
VALUES (..,..,DEFAULT)  ---get default for dateCreated & dateModified   

INSERT INTO Customer (col1, col2,dateCreated,dateModified) 
VALUES (..,..,DEFAULT,DEFAULT)  ---get default for dateCreated & dateModified   

INSERT INTO Customer (col1, col2,dateCreated,dateModified) 
VALUES (..,..,'1/1/2010',DEFAULT)  ---only get default for dateModified   

INSERT INTO Customer (col1, col2,dateCreated,) 
VALUES (..,..,'1/1/2010')  ---only get default for dateModified   

INSERT INTO Customer (col1, col2,dateCreated,dateModified)
VALUES (..,..,'1/1/2010','1/2/2010')  ---no defaults for dateCreated & dateModifie

Мне нравится использовать локальную переменную, установленную в начале процедуры:

DECLARE @RunDate datetime
SET @RunDate=GETDATE()

Затем я использую это в процедуре, поэтому все изменения (даже в нескольких таблицах) имеют одинаковую дату с точностью до миллисекунды. Я также предпочитаю, чтобы столбец dateModified допускал значения NULL и не имел значения по умолчанию. Когда он вставляется, он создается без изменений, я устанавливаю dateModified, когда он фактически изменяется.

затем используйте:

UPDATE Customer
    SET importantColumn=
       ,dateModified = @RunDate
    WHERE ...

UPDATE CustomerPrice
    SET importantColumn=
       ,dateModified = @RunDate
    WHERE ...
0 голосов
/ 13 апреля 2010

1) Обязательно создайте индекс для первичного ключа. (Я только недавно обнаружил ошибку этого типа.)

2) Вы можете использовать один триггер INSERT / UPDATE вместо отдельных триггеров по цене незначительной потери эффективности. Если insert.DateCreated имеет значение null, обновите Vals.DateCreated, в противном случае обновите Vals.DateModified.

0 голосов
/ 10 апреля 2010

@ Kronass, вы не имеете ни малейшего представления о том, что вы говорите!

отметка времени является синонимом типа данных rowversion и зависит от поведения синонимов типа данных,В выражениях DDL везде, где это возможно, используйте метку строки вместо метки времени.Дополнительные сведения см. В разделе Синонимы типов данных (Transact-SQL).

Тип данных временной метки Transact-SQL отличается от типа данных временной метки, определенного в стандарте ISO.

Синтаксис временной меткиосуждается.Эта функция будет удалена в следующей версии Microsoft SQL Server.Избегайте использования этой функции в новых разработках и планируйте изменять приложения, которые в настоящее время используют эту функцию.

rowversion (Transact-SQL) Тип данных, который предоставляет автоматически генерируемые уникальные двоичные числав базе данных.rowversion, как правило, используется в качестве механизма для строк таблицы штампов версий.Размер хранилища составляет 8 байт.Тип данных rowversion является просто инкрементным числом и не сохраняет дату или время.Для записи даты или времени используйте тип данных datetime2.

0 голосов
/ 10 апреля 2010

@ astander прав, вы должны просто использовать триггер обновления, если вы хотите, чтобы это автоматизировалось. Мои триггеры обновления немного отличаются (я использую «вставленную» виртуальную таблицу). Вот тот, который должен соответствовать вашей схеме (переименуйте, если считаете нужным):

CREATE TRIGGER [CustomerDateModifiedTrigger] ON [dbo].[Customer] 
FOR UPDATE
AS
UPDATE Customer
SET dateModified = GETDATE()
FROM Customer c
INNER JOIN inserted i ON c.customerID = i.customerID
0 голосов
/ 09 апреля 2010

Существует тип данных в SQL Server Called timestamp. которые отслеживают версию строки для каждого изменения строки. Или, если хотите, вы можете использовать триггер и изменить столбец ModifiedDate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...