Вставить в таблицу истории и выбрать даты validFrom и validTo на основе содержимого таблицы - PullRequest
0 голосов
/ 30 ноября 2011

Редактировать: Использование SQL-Server 2008

У меня есть таблица AccountHistory, которая имеет несколько столбцов. Для этого случая актуальны Account_FK, ValidTo, ValidFrom

Я пытаюсь вставить новые значения в эту таблицу, используя:

INSERT INTO AccountHistory (Account_FK, ValidTo, ValidFrom)
SELECT Account_FK, ValidTo, ValidFrom
FROM someOtherTable

Проблема в следующем: Если в AccountHistory существует существующая строка с тем же Account_FK, у вставленной строки должна быть установлена ​​текущая дата ValidFrom. ValidTo должен быть нулевым. И старая строка AccountHistory должна иметь дату ValidTo, обновленную с нуля до текущей даты. Если нет другой строки с тем же Account_FK, то для даты validFrom должна быть установлена ​​системная дата начала по умолчанию, например, 1990-01-01

Как это легко и элегантно решается? Я знаю, что триггер может быть вещь, но если есть лучший способ, то я хотел бы услышать ваши предложения.

Поле ValidFrom не является нулевым, поэтому я не могу вставить в него любое нулевое значение.

Ответы [ 2 ]

0 голосов
/ 30 ноября 2011

Самый простой ответ - удалить поле ValidTo, которое фактически является производным полем (которое обычно хранить не предполагается).Затем вам нужно только вставить соответствующие записи, и вы можете получить необходимое значение довольно тривиально (требуется агрегированное самостоятельное объединение).

Однако меня немного беспокоит, что вы переопределяете данное ValidFrom дата, если запись существует - вы фактически делаете невозможным задний ход истории, и новые записи всегда будут «новыми и действующими в настоящее время», что крайне маловероятно.Во-первых, если вы когда-либо вставляете несколько записей, у вас может не быть порядка вставки, который будет гарантированно поставлен, что быстро сработает с этим.Это также делает невозможным заднюю дату записей, если это необходимо (примечание: это не обязательно для гнусных целей - иногда есть веские деловые причины для того, чтобы задним числом «подходящую» историю задним числом. Однако, добавьте метку времени записи для аудита).Кроме того, что происходит, когда у вас есть несколько записей для одного и того же дня - как вы узнаете, какая из них была правильной (поэтому вы уверены, что на самом деле вам не нужна временная метка)?

Кроме этого, вот дваоператоры (проверено в DB2) Я бы использовал для изменения таблицы, как вы описали.
Во-первых, оператор вставки, чтобы позаботиться о новых записях:

INSERT INTO AccountHistory (Account_FK, ValidTo, ValidFrom)
SELECT a.Account_FK, CASE WHEN b.Account_FK IS NULL 
                          THEN a.ValidTo
                          ELSE NULL END,
                     CASE WHEN b.Account_FK IS NULL
                          THEN a.ValidFrom
                          ELSE CURRENT_DATE END
FROM SomeOtherTable as a
LEFT JOIN (SELECT DISTINCT Account_FK
           FROM AccountHistory) as b
ON b.Account_FK = a.Account_FK

И оператор обновления для заполнения 'ValidTo'даты (это получает все, а не только то, что было вставлено):

UPDATE AccountHistory as a SET ValidTo = (SELECT MIN(b.ValidFrom)
                                          FROM AccountHistory as b
                                          WHERE a.Account_FK = b.Account_FK
                                          AND b.ValidFrom > a.ValidFrom)
WHERE ValidTo IS NULL
AND EXISTS (SELECT '1'
            FROM AccountHistory as b
            WHERE a.Account_FK = b.Account_FK
            AND b.ValidFrom > a.ValidFrom)
0 голосов
/ 30 ноября 2011

Если вы используете 2008, вы можете использовать оператор слияния - Решения для ВСТАВКИ И ОБНОВЛЕНИЯ на SQL Server - см. Ответ Кита примерно на треть ниже.Будет ли это работать?

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