Date: Sat, 10 Mar 2001 13:55:39 +0900
From: "Akira Horikawa" <who@example.ne.jp>
堀川です、こんにちは
| > このようにした場合、メインテーブルはうまく処理が完了しCOMMITされても、
| > なんらかの要因で、リレキテーブルのINSERTは失敗し、ROLLBACKがかかり、
| > メインとリレキの同期がとれなくなるのではないか?と、思っています。
>私はそんなことないと思いますけど。
サイトーさん、回答ありがとうございます
トリガ内部で継続実行が不可能な致命的なエラーが発生した場合、
例えばトリガ内部のInsert命令でレコード挿入したときに主キーの
重複エラーが起きた場合
などでは、そのトリガを引き起こした原因となる命令まで含めてロールバック
されます。
更新系命令とその命令によって引き起こされたトリガ内部の処理は、1個の
暗黙のトランザクションを構成します。
見本プログラムを作りましたので、hasegawa さん実行してください。
Testデータベースを使います。
USE Test
GO
SET NOCOUNT ON
GO
IF( (OBJECT_ID('MAIN') IS NOT NULL) AND
OBJECTPROPERTY( OBJECT_ID('MAIN'),'ISTABLE') = 1 )
BEGIN
PRINT '既存のMAINテーブルを削除しました'
DROP TABLE MAIN
END
GO
--MAIN TABLE
CREATE TABLE MAIN (
ID INT CONSTRAINT PK_MAIN PRIMARY KEY ,
DT VARCHAR(20)
)
GO
IF( (OBJECT_ID('MAIN_COPY') IS NOT NULL) AND
OBJECTPROPERTY( OBJECT_ID('MAIN_COPY'),'ISTABLE') = 1 )
BEGIN
PRINT '既存のMAIN_COPYテーブルを削除しました'
DROP TABLE MAIN_COPY
END
GO
--MAIN_COPY TABLE
CREATE TABLE MAIN_COPY (
ID INT CONSTRAINT PK_MAIN_COPY PRIMARY KEY ,
DT VARCHAR(20)
)
GO
--TRIGGER
CREATE TRIGGER TR_MAIN
ON MAIN
FOR DELETE,UPDATE
AS
DECLARE @CNT INT
SET NOCOUNT ON
--削除・更新されたレコード数の取得
--何かで使うかな?
SELECT @CNT = COUNT(ID) FROM DELETED
--DELETEDテーブルのレコードをすべてコピーする
INSERT INTO MAIN_COPY SELECT * FROM DELETED
GO
-- 初期レコードの挿入を行う
INSERT INTO MAIN VALUES( 100 , 'AAAAA')
INSERT INTO MAIN VALUES( 110 , 'BBBBB')
INSERT INTO MAIN VALUES( 120 , 'CCCCC')
INSERT INTO MAIN VALUES( 130 , 'DDDDD')
INSERT INTO MAIN VALUES( 140 , 'EEEEE')
INSERT INTO MAIN VALUES( 150 , 'FFFFF')
-- SELECT * FROM MAIN
GO
--1個のレコードの更新を行って更新前レコードをコピーする
UPDATE MAIN SET DT = '更新します' WHERE( ID = 100 )
PRINT '[MAIN]テーブルのレコード表示'
SELECT * FROM MAIN
PRINT '[MAIN_COPY]テーブルのレコード表示'
SELECT * FROM MAIN_COPY
GO
--2個のレコードの更新を行って更新前レコードをコピーする
UPDATE MAIN SET DT = '更新します' WHERE( (ID = 110) OR (ID=120) )
PRINT '[MAIN]テーブルのレコード表示'
SELECT * FROM MAIN
PRINT '[MAIN_COPY]テーブルのレコード表示'
SELECT * FROM MAIN_COPY
GO
--トリガのレコード挿入で、主キーの重複エラーが起きる場合
UPDATE MAIN SET DT = 'トリガエラー' WHERE( (ID = 120) OR (ID=130) )
GO
--トリガ内のエラーのため、上記更新命令は自動的にロールバックされます
PRINT '[MAIN]テーブルのレコード表示'
SELECT * FROM MAIN
PRINT '[MAIN_COPY]テーブルのレコード表示'
SELECT * FROM MAIN_COPY
GO
余談ですが、SQLServer2000 をまだ購入していない場合は、できる限り
7.0から2000に乗り換えることをおすすめします。
データベース自身のバージョンアップも重要ですが、クエリアナライザが
見違えるほど高機能になりました。
マイクロソフト社が本気を出せば、使いやすい開発ツールも出せるんだ
という証明をしているようなものですね
7.0が明かに手抜きだったのでは?
MSDEユーザのように、2000のアップグレード版を購入するライセンスが
ない場合は、
SQL Server 2000 Evaluation Edition (120日限定評価版)ダウンロード開始!
http://www.microsoft.com/japan/sql/
これを利用したらどうでしょうか?
ぜひ評価版を試され、正式版を購入しましょう。
---------------------------------------------------
(株)日本技術ソフト開発 堀川 明
mailto:who@example.ne.jp
mailto:who@sub.example.jp
http://www.horikawa.ne.jp/msde/
http://www.kt.rim.or.jp/~pwp/
03月10日(土曜日) 13時52分記
[MSDE/SQLServerに関して、今、どんなことにお困りですか?] |
よろしければお困りの内容を、電子メールで教えて下さい。 |
質問を電子メールで作成する
|
[ウィンドを閉じる][MSDE/SQLServer FAQ ][MSDE / MSDE2000 技術サポート情報一覧]
|