INSTEAD OF UPDATE Триггер и обновление первичного ключа - PullRequest
5 голосов
/ 26 октября 2009

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

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

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 голосов
/ 26 октября 2009

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

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

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

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

Если не считать этого, может быть некоторым недокументированным и последовательным порядком между INSERTED и DELETED, так что 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
)

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

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