2009-10-25 4 views
5

を更新します。作業を継続する必要があるデータベースを使用するレガシーソフトウェアのかなり多くもあり、つまり私は、既存のデータベース表、procsの、などを維持したいと思いますINSTEAD OF UPDATEトリガと新しいソフトウェアを開発しながら、私は、既存のデータベースに変更を作っています主キー

現在、私が持っているテーブル

 
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を別のテーブルに移動する必要があります。これは、すべての行で必須ではないためです。だから私は、作成した新しいテーブル: - 私はビューにdbo.t_stationテーブルを変更してまで、トリガの代わりに提供することを決定したので、今

 
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) 
) 

は、私は2つの場所で同じデータを持っている必要はありませんDELETE、INSERT、およびUPDATEを実行します。私は[ほとんどの]彼らが働いている問題はない。

私の質問は、複数の行に主キー列(tx_station_id)とアップデートの更新、INSTEAD OF UPDATEトリガを考えています。私は「更新主キーの後に」「更新前の主キー」とを知っているように、

トリガーブロック内

、挿入、削除[擬似]テーブルを結合する方法はありますか?このような何か...

 
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ステートメントはOKです。その

短いが、そこ OVER ROW_NUMBER()(NULLIF(StationId、StationId)BY ORDER)を使用すると、2つの参加聞かせするように挿入され、DELETED、間にいくつかの文書化されていない&一貫発注かもしれないが、私は思います非常にルートを取ることを躊躇しないでください。非常に、非常に躊躇。

あなたが意図的に、カスケード更新が有効になっていないことがありますか?主キー値を更新できるときに便利です。例:

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()で更新をテストし、ロールバックし、変更が検出された場合はエラーを発生させます。 –

関連する問題