2009-10-25 2 views
5

Я вношу изменения в существующую базу данных при разработке нового программного обеспечения. Существует также довольно много унаследованного программного обеспечения, которое использует базу данных, которая должна продолжать работать, то я хотел бы сохранить существующие таблицы базы данных, проки и т.д.INSTEAD OF UPDATE Trigger and Updating the Primary Key

В настоящее время у меня есть таблица

 
CREATE TABLE dbo.t_station (
    tx_station_id  VARCHAR(4) NOT NULL, 
    tx_description  NVARCHAR(max) NOT NULL, 
    tx_station_type  CHAR(1)  NOT NULL, 
    tx_current_order_num VARCHAR(20) NOT NULL, 

    PRIMARY KEY (tx_station_id) 
) 

Мне нужно включить новое поле в эту таблицу, которое ссылается на завод (производственный объект) и переместить tx_current_order_num в другую таблицу, потому что это не требуется для всех строк. Таким образом, я создал новые таблицы: -

 
CREATE TABLE Private.Plant (
    PlantCode INT   NOT NULL, 
    Description NVARCHAR(max) NOT NULL, 

    PRIMARY KEY (PlantCode) 
) 
CREATE TABLE Private.Station (
    StationId VARCHAR(4) NOT NULL, 
    Description NVARCHAR(max) NOT NULL, 
    StationType CHAR(1)  NOT NULL, 
    PlantCode INT   NOT NULL, 

    PRIMARY KEY (StationId), 

    FOREIGN KEY (PlantCode) REFERENCES Private.Plant (PlantCode) 
) 
CREATE TABLE Private.StationOrder (
    StationId VARCHAR(4) NOT NULL, 
    OrderNumber VARCHAR(20) NOT NULL, 

    PRIMARY KEY (StationId) 
) 

Теперь, я не хочу иметь одни и те же данные в двух местах, так что я решил изменить таблицу dbo.t_station в представление и обеспечить вместо триггеров выполните DELETE, INSERT и UPDATE. Без проблем у меня есть [большинство из них] работающих.

Мой вопрос касается триггера INSTEAD OF UPDATE, обновления столбца первичного ключа (tx_station_id) и обновления до нескольких строк.

Внутри триггерного блока есть ли способ присоединиться к вставленным и удаленным таблицам [psuedo], чтобы я знал «первичный ключ до обновления» и «после первичного ключа обновления»? Что-то вроде этого ...

 
UPDATE sta 
    SET sta.StationId = ins.tx_station_id 
    FROM Private.Station AS sta 
     INNER JOIN deleted AS del 
      INNER JOIN inserted AS ins 
       ON ROW_IDENTITY_OF(del) = ROW_IDENTITY_OF(ins) 
      ON del.tx_station_id = sta.StationId 

На этом этапе я поставил галочку в блоке триггера, что откаты обновление, если столбец первичного ключа обновляется, и есть более чем одна строка в вставленный или удален , Таблица.

+1

Я надеялся, что у кого-то может быть лучший ответ! Эта проблема тоже досадила мне в прошлом. –

ответ

3

Короткий ответ - нет.

может положить суррогатный ключ на Private.Station и выставить его через представление и использовать для идентификации до и после значений. Вам не нужно было бы менять отношение первичного ключа или внешнего ключа, но вам нужно было бы открыть какой-то невоспроизводимый крут через представление, чтобы он появился в псевдо-таблицах. например:

alter table Private.Station add StationSk int identity(1,1) not null 

Примечание. Это может привести к повреждению устаревшего приложения, если оно использует SELECT *. Однако инструкции INSERT без явных списков столбцов вставки должны быть в порядке.

Короткие, что там может быть некоторые недокументированные & последовательное упорядочение между INSERTED и удалений, так что ROW_NUMBER() OVER (ORDER BY NULLIF (StationId, StationId)) пусть бы вы присоединиться к два, но я бы будьте очень нерешительны, чтобы пройти по маршруту. Очень, очень нерешительно.

Вы намеренно не включили каскадные обновления? Они полезны, когда значения первичного ключа могут быть обновлены. например:

CREATE TABLE Private.Station (
    StationId VARCHAR(4) NOT NULL, 
    Description NVARCHAR(max) NOT NULL, 
    StationType CHAR(1)  NOT NULL, 
    PlantCode INT   NOT NULL, 
    PRIMARY KEY (StationId), 
    FOREIGN KEY (PlantCode) REFERENCES Private.Plant (PlantCode) 
     ON UPDATE CASCADE 
     -- maybe this too: 
     -- ON DELETE CASCADE 
) 

У кого-то может быть лучший трюк. Подождите и смотрите!

+0

Да, подумал о суррогатной ключевой идее, но я хотел точно сохранить имя таблицы и столбцы. Что касается каскадных обновлений и удалений, которые не будут работать для моей основной задачи. StationId ссылается по всей базе данных, и я хочу убедиться, что ссылочные таблицы продолжают ссылаться на правильную, логическую, станцию. – Kepboy

+0

Я должен указать, что я не полностью недоволен решением одной строки, просто подумал, что я спрошу, потому что мне нравится это знать. – Kepboy

+0

Разрешены ли изменения в t_station.tx_station_id в текущей схеме? Если нет, проверьте наличие обновлений с помощью COLUMNS_UPDATED(), отката и вызовите ошибку, если вы обнаружите какие-либо изменения. –

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