MSDE FunClub | 最終更新日 : 2000/08/17 | |
Microsoft Data Engine FunClub |
|
|
SQLServer7.0/MSDE 完全トレーニングテキスト(上巻) | ||
【第6章336p 〜 339p掲載】 |
-- [SQL06_01.SQL] -- SQLServer7.0 Transact-SQL言語 -- 日本技術ソフト開発 堀川 明 -- http://www.horikawa.ne.jp/msde/ -- -- このSQLプログラムは、 -- deletedテーブルにカーソルを設定し、1レコード単位 -- でその調査を行う例題です -- -- カレントデータベースを MySampleTest にする USE MySampleTest GO -- (件処理されました)のメッセージを抑止する SET NOCOUNT ON GO -- ************************************************* -- 見本テーブルの作成 -- ************************************************* -- 既存テーブルが存在したら削除します IF( (object_id('TRI_TEST') IS NOT NULL) AND OBJECTPROPERTY( object_id('TRI_TEST'),'ISTABLE') = 1 ) BEGIN -- PRINT 'テーブルが存在したので削除しました' DROP TABLE TRI_TEST END GO -- 新しくテーブルを作成する CREATE TABLE TRI_TEST ( -- 主キー ID int PRIMARY KEY , -- 適当なデータです DATA varchar(10) , ) GO -- ************************************************* -- トリガの登録 -- ************************************************* CREATE TRIGGER TR_TEST -- トリガの名前 ON TRI_TEST -- トリガを組み込むテーブル ----------- FOR DELETE,UPDATE ----------- AS -- (件処理しました)のメッセージを抑止する SET NOCOUNT ON DECLARE @cnt int , @id int , @data varchar(10) DECLARE @flag int DECLARE @msg varchar(256) SELECT @cnt = 0 , @flag = 0 -- 削除や更新されたレコード数を取得する SELECT @cnt = COUNT(*) FROM deleted -- 削除・更新対象レコードが2レコード以上ありますか? -- 複数レコードのときは、カーソルを使います IF( @cnt>1 ) BEGIN --削除前・更新前のレコード調査を行なうために --deletedテーブルに対してカーソルを定義 DECLARE TRI_CUR INSENSITIVE CURSOR FOR SELECT * FROM deleted FOR READ ONLY --カーソルを開く OPEN TRI_CUR --更新前の値を取得し、文字列を作成する RAISERROR('トリガdeletedの主キーの値を出力します',0,1) SELECT @msg = '' --先頭レコードを取得する FETCH NEXT FROM TRI_CUR INTO @id , @data --レコードの存在する間、繰り返す WHILE( @@FETCH_STATUS = 0 ) BEGIN --出力用文字列の作成 SELECT @msg = @msg + '[' + CAST(@id AS char(2)) + ']' -- ID=2 のレコードの更新・削除は認めません IF( @id = 2 ) SELECT @flag = 1 -- 次のレコードを取得 FETCH NEXT FROM TRI_CUR INTO @id , @data END --メッセージの出力 RAISERROR('%sが更新対象です',0,1,@msg) WITH NOWAIT --カーソルを閉じる CLOSE TRI_CUR --カーソルを破棄する DEALLOCATE TRI_CUR --ID=2がありましたか? IF( @flag = 1 ) BEGIN -- 変更操作は認めません ROLLBACK TRANSACTION -- エラーメッセージを出力します -- ここでは第2引数を0にしていますが、一般的には16にしてください RAISERROR('ID=2の削除・更新は一切認めません!!',0,1) WITH NOWAIT END -- トリガを終了します RETURN END --/////////////////////// -- 1レコード操作の場合 --/////////////////////// SELECT @id=ID , @data=DATA from deleted RAISERROR('[**1レコード操作**]トリガdeletedの主キーの値 = %d',0,1,@id) WITH NOWAIT IF( @id = 2 ) BEGIN -- 変更操作は認めません ROLLBACK TRANSACTION -- エラーメッセージを出力します -- ここでは第2引数を0にしていますが、一般的には16にしてください RAISERROR('ID=2の削除・更新は一切認めません!!',0,1) WITH NOWAIT END RETURN GO -- ************************* -- データ登録処理の実行 -- ************************* INSERT INTO TRI_TEST VALUES( 1 , 'A1' ) INSERT INTO TRI_TEST VALUES( 2 , 'A2' ) INSERT INTO TRI_TEST VALUES( 3 , 'B1' ) INSERT INTO TRI_TEST VALUES( 4 , 'B2' ) SELECT * FROM TRI_TEST GO -- ************************* -- トリガの起動 -- ************************* --複数レコード同時操作 UPDATE TRI_TEST SET DATA = 'C' + CAST(ID AS char(1)) WHERE data like 'B%' SELECT * FROM TRI_TEST GO --このUPDATE文は、ID=2 を含むため、認められません --複数レコード同時操作 UPDATE TRI_TEST SET DATA = 'D' + CAST(ID AS char(1)) WHERE data like 'A%' GO --このUPDATE文は、ID=2 を含むため、認められません --1レコード操作 UPDATE TRI_TEST SET DATA = 'E2' WHERE( ID = 2 ) GO