web-dev-qa-db-ja.com

挿入トリガーと主キーの問題

変更やサポートを受けられないサードパーティのアプリを扱っています。基になるテーブルをいくつかの方法で変更して、機能を強化しました

1-テーブルの名前をPRE_CASEからPRE_TCASEに変更しました
2- PRE_CASEという名前のビューを作成しました。これは、PRE_TCASEに対する選択であり、リンクされたサーバーのDBおよびOTHERSYSTEM_CASEという名前のテーブルに対するUNION ALLを使用します。

これは、アプリがだまされてPRE_TCASEとOTHERSYSTEM_CASEのデータをエンドユーザーに表示することで、テーブルPRE_CASEを参照していると思われる場合に機能します。ただし、データの挿入は失敗します。これを試して修正するには、トリガーを作成しました(PRE_TCASEに挿入するだけで、OTHERSYSTEM_CASEは不要です)。

create TRIGGER INSREPLACE
   ON  dbo.pre_case
   INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;

    INSERT INTO dbo.PRE_TCASE
    (col1, col2, col3, etc.)
    SELECT col1, col2, col3, etc.
    FROM Inserted

END

次のエラーで挿入が失敗します。

メッセージ233、レベル16、状態2、行1テーブル 'dbo.pre_case'の列 'ID'をnullにすることはできません。

挿入ステートメントは次の形式です

INSERT INTO dbo.pre_case (col1, col2, col3)
values (1,2,3)

ID列への値/参照は行われません。

基本となるPRE_CASEでは、列IDは有効なIDシードを持つ整数の主キー(PK、int、nullではない)です。 PRE_CASEへの直接挿入は機能しますが、新しいビューおよびトリガーへの挿入は機能しません。見落としていることは何ですか?

(私の最終ソリューションはSQL2000、SQL2005およびSQL2008R2ボックスに配備されますが、SQL2000でテスト/開発しています)

編集:このモデルを作成して、より孤立した方法でテストしました。エラーはSQL2008R2ではなくSQL2000で発生することが判明しました。個人的に私はこの時点で諦めています。

create table t1(id int  IDENTITY(1,1) PRIMARY KEY ,ltext varchar(100));
create table t2(id int IDENTITY(1,1) PRIMARY KEY,ltext varchar(100));

CREATE VIEW tv AS
SELECT id, ltext from t1
union all
SELECT id, ltext from t2

select * from t2;
select * from tv;

INSERT  t1(ltext) values ('test1a');
INSERT  t1(ltext) values ('test1b');
INSERT  t1(ltext) values ('test1c');
INSERT  t2(ltext) values ('test2a');
INSERT  t2(ltext) values ('test2b');
INSERT  t2(ltext) values ('test2c');  



CREATE TRIGGER TRG_TV ON tv
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
INSERT t2(ltext)
select ltext from inserted

END

-- this errors on SQL2000
INSERT  tv(ltext) values ('testv-a');
1
Paul

最初は、これはINSERT INTOトリガーではなく、INSERT INTO pre_caseが原因であると考えました。しかし、より多くの情報が提供された後、それはそうではなかったことが判明しました。

Googleの結果から判断すると、これはINSTEAD OFトリガーとおそらくID列の一般的なエラーです。 INTEAD OFトリガーが起動したときにその列の値が生成されていないため、IDからNULLになります。列をNULL可能に変更してから、新しいテーブルのID列に何が表示されるかを確認します。あなたがそれに価値があるなら、あなたは行ってもいいです。そうでない場合は、生成する必要があるようです。

(私の最終ソリューションはSQL2000、SQL2005およびSQL2008R2ボックスに配備されますが、SQL2000でテスト/開発しています)

クレイジー

2
Tara Kizer

これは、SQL2000の下では機能しません。ダミーのID値を指定した場合:

INSERT  tv(id, ltext) values (0, 'testv-a');

その後、機能し、0は無視され、ID値が生成されます。しかし、質問のシナリオでは、挿入ステートメントはサードパーティの実行可能ファイルによって堅固に設定されているため、機能しません。

0
Paul