SQL Server 2008: обновление и отслеживание ежегодного повышения цен - PullRequest
3 голосов
/ 12 марта 2012

У меня сейчас есть проект, в котором мне нужно обновить цены на список продуктов.Цены указаны с 01.01.2007 по 31.12.2011, и мне нужно увеличивать эти цены на 5% каждый год до конца 2015 года.

Вот что у меня есть.Но я застреваю при обновлении цен (то есть на 5%).Я продолжаю получать сообщение об ошибке о повторяющихся данных.Заранее благодарим за любую помощь / подсказки!

Сообщение об ошибке:

Сообщение 2627, Уровень 14, Состояние 1, Процедура update_history, строка 9
Нарушение ограничения PRIMARY KEY 'PK_ PriceCha _207F7DE23A81B327'.Невозможно вставить дубликат ключа в объект 'dbo.PriceChange_History'.

Таблицы:

create table PriceChange
(ProductID INTEGER NOT NULL PRIMARY KEY,
 StartDate DATE,
 EndingDate DATE,
 UnitPrice MONEY);


ALTER TABLE PriceChange ADD FOREIGN KEY (ProductID) REFERENCES PRODUCT(ProductID)


create table PriceChange_History
(History_ProductID INTEGER NOT NULL PRIMARY KEY,
 History_StartDate DATE,
 History_EndingDate DATE,
 History_UnitPrice MONEY,
 Modified_date datetime,
 ChangeType varchar(20) );

ALTER TABLE PriceChange_History 
ADD FOREIGN KEY (History_ProductID) REFERENCES PRODUCT(ProductID)

Триггеры

create trigger [insert_history] on PriceChange
for insert
as  
    insert PriceChange_History (History_ProductID, History_StartDate, 
                                History_EndingDate, History_UnitPrice,
                                Modified_date, ChangeType)
        select 
            ProductID, StartDate, EndingDate, UnitPrice,
            GETDATE(), 'INSERTED'
        from inserted

create trigger [update_history] on PriceChange
for update
as
   insert PriceChange_History(History_ProductID, History_StartDate,
                              History_EndingDate, History_UnitPrice,
                              Modified_date, ChangeType)
       select 
           ProductID, StartDate, EndingDate, UnitPrice,
           GETDATE(), 'BEFORE UPDATE'
       from deleted

   insert PriceChange_History(History_ProductID, History_StartDate,
                              History_EndingDate, History_UnitPrice,
                              Modified_date, ChangeType)
      select     
          ProductID, StartDate, EndingDate, UnitPrice,
          GETDATE(), 'AFTER UPDATE'
      from inserted

ВСТАВИТЬ + ОБНОВЛЕНИЕ

INSERT INTO PriceChange 
VALUES(1,'1/1/2007', '12/31/2011', 500) <---  this will record the query into both pricechange and pricechange history

UPDATE PriceChange 
SET UnitPrice = (UnitPrice * 1.05),
    StartDate = '1/1/2012',
    EndingDate = '12/31/2012' 
WHERE 
    ProductID = 1

UPDATE PriceChange 
SET UnitPrice = (UnitPrice * 1.05),
    StartDate = '1/1/2013',
    EndingDate = '12/31/2013' 
WHERE 
    ProductID = 1

UPDATE PriceChange 
SET UnitPrice = (UnitPrice * 1.05),
    StartDate = '1/1/2014',
    EndingDate = '12/31/2014' 
WHERE 
    ProductID = 1

UPDATE PriceChange 
SET UnitPrice = (UnitPrice * 1.05),
    StartDate = '1/1/2015',
    EndingDate = '12/31/2015' 
WHERE
    ProductID = 1

Ответы [ 2 ]

4 голосов
/ 12 марта 2012

price_history имеет PK на ProductID, поэтому он не может иметь дубликаты продуктов. Я бы добавил личность первичного ключа.

0 голосов
/ 12 марта 2012

Первое, на что я обращаю внимание, это то, что данные вашей таблицы PriceChange могут быть получены из таблицы PriceChange_History.

Если есть причина, по которой вы должны хранить таблицу PriceChange, а не предоставлять ее через представление, я бы начал с добавления столбца идентификаторов в виде PK в обе таблицы. Я настоятельно рекомендую, чтобы таблицы всегда имели простой столбец идентификаторов ... вы будете рады, что сделали это рано или поздно :-) Затем добавьте соответствующий уникальный кластеризованный ключ в PriceChange: ProductId, StartDate, EndDate. Затем свяжите таблицу PriceChange_History с идентификатором PriceChange PK вместо productId. Наконец, добавьте соответствующий уникальный кластеризованный ключ в PriceChange_History: PriceChangeId, ModifiedDate.

Теперь вы готовы соответствующим образом обновить связанные триггеры, функции и т. Д. И сможете вставить несколько строк PriceChange в таблицу PriceChange_History.

Обновление Только из вашей текущей таблицы истории текущая информация о ценах может быть получена в представлении с логикой ниже:

Select 
    LastChangeDetails.ProductId,
    ProductChangeDetails.StartDate,
    ProductChangeDetails.EndDate,
    ProductChangeDetails.UnitPrice
    (
        Select 
            History_ProductId, 
            Max(Modified_date) as LastModifiedDate
        From PriceChange_History
    ) as LastChange
Join PriceChange_History as LastChangeDetails
    on LastChangeDetails.History_productId = LastChange.ProductId
and LastChangeDetails.modified_Date = LastChange.LastChangeDate --assumes the most recently modified information is the 'most correct'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...