2015-10-01 3 views
1

Если записи обновлены, они будут отмечены значком Y, а последняя версия будет отмечена нулем. CreationDate из последней обновленной записи следует взять из ModificationDate предыдущей записи. Но поле неправильно обновляется, как показано на скриншоте. Кто-нибудь знает, как решить эту ошибку?Значения полей SQL не точно обновляются

Если значение поля CreationDate является точным, записи должны быть в порядке no. 6, 8, 7

CREATE TRIGGER CloneAfterUpdate ON ProcessList 
AFTER UPDATE 
AS 
IF (UPDATE (Amount) OR UPDATE (NAME)) 
BEGIN 
    INSERT INTO ProcessListHist (
     ID 
     ,NAME 
     ,Amount 
     ,CreationDate 
     ,Edited 
     ,ModificationDate 
     ) 
    SELECT ID 
     ,NAME 
     ,Amount 
     ,CreationDate 
     ,'Y' 
     ,GETDATE() 
    FROM deleted 

    UPDATE ProcessList 
    SET ProcessList.CreationDate = ProcessListHist.ModificationDate 
    FROM ProcessList 
    INNER JOIN ProcessListHist ON ProcessList.ID = ProcessListHist.ID 
END 

UPDATE ProcessList 
SET Amount = 9800 
WHERE NAME = 'Rachel' 

SELECT * 
FROM ProcessList 

UNION ALL 

SELECT * 
FROM ProcessListHist 
ORDER BY ID ASC ,CreationDate ASC 

--- Обновлено ---

CREATE TABLE dbo.ProcessList 
(
    Edited    varchar(1), 
    ID     integer   NOT NULL, 
    Name    varchar(30)  NOT NULL, 
    Amount    smallmoney  NOT NULL, 
    CreationDate  datetime  DEFAULT GETDATE(), 
    ModificationDate datetime, 
    PRIMARY KEY (ID, CreationDate) 
) 


CREATE TABLE dbo.ProcessListHist 
(
    Edited    varchar(1), 
    ID     integer   NOT NULL, 
    Name    varchar(30)  NOT NULL, 
    Amount    smallmoney  NOT NULL, 
    CreationDate  datetime  NOT NULL, 
    ModificationDate datetime, 
    PRIMARY KEY (ID, CreationDate) 
) 
+0

Я думаю, что это действительно поможет, если вы укажете структуры таблиц, которые используете, потому что сейчас мы вынуждены их угадывать. Первичным ключом для обеих таблиц является ID + CreationDate? – Andrew

+0

@eyeballs Ваша колонка Edited, вероятно, избыточна. Вы можете использовать для этого только 'CreationDate' и' ModificationDate'. Таким образом, не обновленные записи имели бы 'ModificationDate' NULL. – lad2025

ответ

1

UPDATE в вашем триггере ничего не фильтрует, поэтому она будет проходить через все строки, возвращаемые

FROM ProcessList 
INNER JOIN ProcessListHist ON ProcessList.ID = ProcessListHist.ID 

и присвоить каждому ModificationDate к ProcessList, каждый раз, перезаписывая предыдущее значение, и, следовательно, вы оказываетесь последним, что бы это ни было. Вам нужно получить данные только измененной строки, так что вам нужно, чтобы присоединиться к delete таблицу, как это:

UPDATE PL 
SET PL.CreationDate = PLH.ModificationDate 
FROM ProcessList PL 
INNER JOIN deleted on PL.ID = deleted.ID AND PL.CreationDate = deleted.CreationDate 
INNER JOIN ProcessListHist PLH ON PL.ID = PLH.ID AND PLH.CreationDate = deleted.CreationDate 

Присоединившись с delete, вы сначала получить модифицированную строку, а затем вы можете присоединиться к истории таблицу, чтобы получить новую дату изменения.

Но если вы обратили внимание, вы присоединяетесь эту последнюю таблицу просто получить datetime вы уже имели (если вы назвали GETDATE), так что вы можете упростить курок немного так:

DECLARE @Now DATETIME 
SELECT @Now = GETDATE() 
INSERT INTO ProcessListHist (
    ID 
    ,NAME 
    ,Amount 
    ,CreationDate 
    ,Edited 
    ,ModificationDate 
    ) 
SELECT ID 
    ,NAME 
    ,Amount 
    ,CreationDate 
    ,'Y' 
    ,@Now 
FROM deleted 

UPDATE PL 
SET PL.CreationDate = @Now 
FROM ProcessList PL 
INNER JOIN deleted on PL.ID = deleted.ID AND PL.CreationDate = deleted.CreationDate 

Значит ли ProcessList нужно поле ModificationDate? Зачем вам поле Edited? Из того, что я вижу, всегда NULL в одном и всегда Y в другом. Если вы удалите их все, вы можете сделать последний запрос, как это:

SELECT NULL AS Edited, ID, Name, Amount, CreationDate, NULL AS ModificationDate 
FROM ProcessList 

UNION ALL 

SELECT 'Y', ID, Name, Amount, CreationDate, ModificationDate 
FROM ProcessListHist 
ORDER BY ID ASC ,CreationDate ASC 
+0

Ах да, мне нужно поле ModificationDate, так как моя база данных позволяет пользователям импортировать в него файлы excel, поэтому, если они что-то редактируют вне базы данных, это показывает. Моя база данных работает так, как я хочу ее сейчас. Большое вам спасибо за ваше время и помощь! :> @Andrew –

1

Я не вижу никаких причин сделать вашу жизнь настолько сложна, с тем, как вы используете.

Позволяет понять это один за другим. У вас есть следующая структура таблицы, и у вас есть две операции, то есть Insert и Delete.

CREATE TABLE dbo.ProcessList 
(
    Edited    varchar(1), 
    ID     integer   NOT NULL, 
    Name    varchar(30)  NOT NULL, 
    Amount    smallmoney  NOT NULL, 
    CreationDate  datetime  DEFAULT GETDATE(), 
    ModificationDate datetime, 
    PRIMARY KEY (ID, CreationDate) 
) 

Вставка

В случае INSERT, редактирование будет нулевым (что само по себе является недостатком конструкции, будет обсуждаться позже), ID-Имя-Сумма-CreationDate будет имеют значение, а ModificationDate снова будет NULL. Это простой вариант использования.

Insert into YouTableName values (null,4035,'Rachel Zane',1000,getdate(),null) 

Update/Edit

В случае EDIT, вам необходимо обновляемой колонке EDIT для 'Y' и вы будете обновлять остальные поля, и просто скопировать ModificationDate в CreationDate как ниже

Update table 
set Edit = 'Y', 
Name = <NewNameIfAny>, 
Amount = <NewAmountIfAny>, 
CreationDate = ModificationDate, 
ModificationDate = Getdate() 

Вот и все, и вы сделали, и таким образом, вам не нужно никакого Trigger. И я не вижу никакого варианта использования для того же самого. Вы можете прочитать here вариант использования триггера.

DesignFlaw: Когда вы знаете, что вы либо собираетесь быть «Y» или «нулевой» в колонке EDIT, то почему не сделать его из bit типа, который быстрее, чем что-либо. Бит будет действовать как флаг для вас. Первоначально вы можете пометить его как False (0), и всякий раз, когда происходит какое-либо редактирование, обновите его до True (1). Вот и все. И вы можете переименовать свою колонку в IsEdited.

+0

спасибо за указание на дефектную часть! Будут реализовывать его в моей базе данных:> Большое вам спасибо! –

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