SlideShare ist ein Scribd-Unternehmen logo
1 von 83
Downloaden Sie, um offline zu lesen
id   name    pass   is_deleted
1     ryu    xxx     FALSE
2     ken    xxx     FALSE
3    honda   xxx      TRUE
id   name    pass   is_deleted
1     ryu    xxx     FALSE
2     ken    xxx     FALSE
3    honda   xxx      TRUE



3    honda   xxx     FALSE
WHERE is_deleted = false
WHERE is_deleted = false
WHERE is_deleted = false
DELETE FROM users WHERE id = 2;
UPDATE user SET is_update = true WHERE id = 2;
id   name   pass   is_deleted
1    ryu    xxx      TRUE
2    ryu    xxx      TRUE
3    ryu    xxx     FALSE
4    ryu    xxx     FALSE
id   name   pass   is_deleted
1    ryu    xxx      TRUE
2    ryu    xxx      TRUE
3    ryu    xxx     FALSE
4    ryu    xxx     FALSE
--
CREATE TABLE users (
    id          SERIAL PRIMARY KEY,
    name        TEXT,
    pass        TEXT,
    is_deleted BOOL DEFAULT false
);

--
CREATE UNIQUE INDEX users_valid_constraint
    ON users (name) WHERE NOT is_deleted;
--	 テーブルを作成する
CREATE	 TABLE	 users	 (
	 	 	 	 id	 	 	 	 	 	 	 	 	 	 SERIAL	 PRIMARY	 KEY,
	 	 	 	 name	 	 	 	 	 	 	 	 TEXT,
	 	 	 	 pass	 	 	 	 	 	 	 	 TEXT,
	 	 	 	 is_deleted	 	 BOOL	 DEFAULT	 false
);
--	 一意な部分インデックスを張る
CREATE	 UNIQUE	 INDEX	 users_valid_constraint
	 	 	 	 ON	 users	 (name)	 WHERE	 NOT	 is_deleted;
--	 ryuを登録する
testdb=#	 INSERT	 INTO	 users	 (name,	 pass,	 is_deleted)
testdb-#	 VALUES	 ('ryu',	 'xxx',	 false);
INSERT	 0	 1

--	 登録したデータを確認
testdb=#	 SELECT	 *	 FROM	 users;
	 id	 |	 name	 |	 pass	 |	 is_deleted	 
----+------+------+------------
	 	 1	 |	 ryu	 	 |	 xxx	 	 |	 f
(1	 row)
--	 更にもう一件重複するryuを登録する
testdb=#	 INSERT	 INTO	 users	 (name,	 pass,	 is_deleted)
testdb-#	 VALUES	 ('ryu',	 'xxx',	 false);
ERROR:	 	 duplicate	 key	 value	 violates	 unique	 constraint	 
"users_valid_constraint"
DETAIL:	 	 Key	 (name)=(ryu)	 already	 exists.
--	 削除フラグを立ててryuを削除したことにする
testdb=#	 UPDATE	 users	 SET	 is_deleted	 =	 true
testdb-#	 WHERE	 id	 =	 1;
UPDATE	 1

--	 ryuが論理削除されたことを確認
testdb=#	 SELECT	 *	 FROM	 users;
	 id	 |	 name	 |	 pass	 |	 is_deleted	 
----+------+------+------------
	 	 1	 |	 ryu	 	 |	 xxx	 	 |	 t
(1	 row)
--	 ryuは削除されているのでryuを登録する
testdb=#	 INSERT	 INTO	 users	 (name,	 pass,	 is_deleted)
testdb-#	 VALUES	 ('ryu',	 'xxx',	 false);
INSERT	 0	 1

--	 登録したデータを確認する
testdb=#	 SELECT	 *	 FROM	 users;
	 id	 |	 name	 |	 pass	 |	 is_deleted	 
----+------+------+------------
	 	 1	 |	 ryu	 	 |	 xxx	 	 |	 t
	 	 3	 |	 ryu	 	 |	 xxx	 	 |	 f
(2	 rows)
--	 削除フラグを戻して削除したryuを復活させる
testdb=#	 UPDATE	 users	 SET	 is_deleted	 =	 false
testdb-#	 WHERE	 id	 =	 1;
ERROR:	 	 duplicate	 key	 value	 violates	 unique	 constraint	 
"users_valid_constraint"
DETAIL:	 	 Key	 (name)=(ryu)	 already	 exists.
--	 現在のデータを確認する
testdb=#	 SELECT	 *	 FROM	 users;
	 id	 |	 name	 |	 pass	 |	 is_deleted	 
----+------+------+------------
	 	 1	 |	 ryu	 	 |	 xxx	 	 |	 t
	 	 3	 |	 ryu	 	 |	 xxx	 	 |	 f
(2	 rows)

--	 削除されていない方のryuを論理削除する
testdb=#	 UPDATE	 users	 SET	 is_deleted	 =	 true
testdb-#	 WHERE	 id	 =	 3;

--	 論理削除されたryuは2件あることを確認
testdb=#	 SELECT	 *	 FROM	 users;
	 id	 |	 name	 |	 pass	 |	 is_deleted	 
----+------+------+------------
	 	 1	 |	 ryu	 	 |	 xxx	 	 |	 t
	 	 3	 |	 ryu	 	 |	 xxx	 	 |	 t
(2	 rows)
☓☓
☓☓
--	 ユーザテーブルを作成する                     --	 エントリーテーブルを作成する
CREATE	 TABLE	 users	 (              CREATE	 TABLE	 entries	 (
	 	 user_id	 SERIAL	 NOT	 NULL,      	 	 entry_id	 SERIAL	 	 NOT	 NULL,
	 	 name	 	 	 	 TEXT,                	 	 user_id	 	 INTEGER	 NOT	 NULL,
	 	 pass	 	 	 	 TEXT,                	 	 event_id	 INTEGER	 NOT	 NULL,
	 	 PRIMARY	 KEY(user_id)            	 	 stat	 	 	 	 	 TEXT	 NOT	 NULL,
);                                   	 	 message	 	 TEXT,
                                     	 	 PRIMARY	 KEY(entry_id),
--	 イベントテーブルを作成する                    	 	 FOREIGN	 KEY(user_id)
CREATE	 TABLE	 events	 (             	 	 	 	 REFERENCES	 users(user_id)
	 	 event_id	 SERIAL	 	 NOT	 NULL,   	 	 	 	 	 	 ON	 DELETE	 CASCADE
	 	 user_id	 	 INTEGER	 NOT	 NULL,   	 	 	 	 	 	 ON	 UPDATE	 CASCADE,
	 	 name	 	 	 	 	 TEXT,              	 	 FOREIGN	 KEY(event_id)
	 	 PRIMARY	 KEY(event_id),          	 	 	 	 REFERENCES	 events(event_id)
	 	 FOREIGN	 KEY(user_id)            	 	 	 	 	 	 ON	 DELETE	 CASCADE
	 	 	 	 REFERENCES	 users(user_id)   	 	 	 	 	 	 ON	 UPDATE	 CASCADE,
	 	 	 	 	 	 ON	 DELETE	 CASCADE      	 	 UNIQUE(user_id,	 event_id)
	 	 	 	 	 	 ON	 UPDATE	 CASCADE      );
);
--	 一意な部分インデックスを張る(IDを利用)
CREATE	 UNIQUE	 INDEX	 users_valid_constraint
	 	 	 	 ON	 users	 (name)	 WHERE	 0	 <	 user_id;
--	 テストデータを投入する
INSERT	 INTO	 users	 (name,	 pass)	 VALUES	 ('ryu',	 'xxx');
INSERT	 INTO	 users	 (name,	 pass)	 VALUES	 ('ken',	 'xxx');

INSERT	 INTO	 events	 (user_id,	 name)	 VALUES	 (1,	 '〇〇勉強会');
INSERT	 INTO	 events	 (user_id,	 name)	 VALUES	 (1,	 '××勉強会');
INSERT	 INTO	 events	 (user_id,	 name)	 VALUES	 (2,	 '△△勉強会');

INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)
	 	 	 	 VALUES	 (1,	 1,	 '参加',	 'いち');
INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)	 
	 	 	 	 VALUES	 (1,	 2,	 '参加',	 '参加します');
INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)	 
	 	 	 	 VALUES	 (2,	 1,	 'キャンセル',	 'ごめんね');
INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)
	 	 	 	 VALUES	 (2,	 2,	 '参加',	 'にばん');
INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)
	 	 	 	 VALUES	 (3,	 2,	 '参加',	 'よろしく');
--	 テストデータを確認する
testdb=#	 SELECT	 *	 FROM	 users;
	 user_id	 |	 name	 |	 pass	 
---------+------+------
	 	 	 	 	 	 	 1	 |	 ryu	 	 |	 xxx
	 	 	 	 	 	 	 2	 |	 ken	 	 |	 xxx
(2	 rows)
testdb=#	 SELECT	 *	 FROM	 events;
	 event_id	 |	 user_id	 |	 	 	 	 name	 	 	 	 
----------+---------+------------
	 	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 1	 |	 〇〇勉強会
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 1	 |	 ××勉強会
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 2	 |	 △△勉強会
(3	 rows)
testdb=#	 SELECT	 *	 FROM	 entries;;
	 entry_id	 |	 user_id	 |	 event_id	 |	 	 	 	 stat	 	 	 	 |	 	 message	 	 	 
----------+---------+----------+------------+------------
	 	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 	 1	 |	 参加	 	 	 	 	 	 	 |	 いち
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 1	 |	 参加	 	 	 	 	 	 	 |	 参加します
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 	 2	 |	 キャンセル	 |	 ごめんね
	 	 	 	 	 	 	 	 4	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 2	 |	 参加	 	 	 	 	 	 	 |	 にばん
	 	 	 	 	 	 	 	 5	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 3	 |	 参加	 	 	 	 	 	 	 |	 よろしく
(5	 rows)
--	 イベントを論理削除する
UPDATE	 events	 SET	 event_id	 =	 event_id	 *	 -1	 WHERE	 event_id	 =	 1;
--	 参照しているテーブルを確認する
testdb=#	 SELECT	 *	 FROM	 users;
	 user_id	 |	 name	 |	 pass	 
---------+------+------
	 	 	 	 	 	 	 1	 |	 ryu	 	 |	 xxx
	 	 	 	 	 	 	 2	 |	 ken	 	 |	 xxx
(2	 rows)
testdb=#	 SELECT	 *	 FROM	 events;
	 event_id	 |	 user_id	 |	 	 	 	 name	 	 	 	 
----------+---------+------------
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 1	 |	 ××勉強会
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 2	 |	 △△勉強会
	 	 	 	 	 	 	 -1	 |	 	 	 	 	 	 	 1	 |	 〇〇勉強会
(3	 rows)
testdb=#	 SELECT	 *	 FROM	 entries;
	 entry_id	 |	 user_id	 |	 event_id	 |	 	 	 	 stat	 	 	 	 |	 	 message	 	 	 
----------+---------+----------+------------+------------
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 	 2	 |	 キャンセル	 |	 ごめんね
	 	 	 	 	 	 	 	 4	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 2	 |	 参加	 	 	 	 	 	 	 |	 にばん
	 	 	 	 	 	 	 	 5	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 3	 |	 参加	 	 	 	 	 	 	 |	 よろしく
	 	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 -1	 |	 参加	 	 	 	 	 	 	 |	 いち
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 -1	 |	 参加	 	 	 	 	 	 	 |	 参加します
(5	 rows)
--	 ユーザを論理削除する
UPDATE	 users	 SET	 user_id	 =	 user_id	 *	 -1	 WHERE	 user_id	 =	 2;
--	 参照しているテーブルを確認する
testdb=#	 SELECT	 *	 FROM	 users;
	 user_id	 |	 name	 |	 pass	 
---------+------+------
	 	 	 	 	 	 	 1	 |	 ryu	 	 |	 xxx
	 	 	 	 	 	 -2	 |	 ken	 	 |	 xxx
(2	 rows)
testdb=#	 SELECT	 *	 FROM	 events;
	 event_id	 |	 user_id	 |	 	 	 	 name	 	 	 	 
----------+---------+------------
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 1	 |	 ××勉強会
	 	 	 	 	 	 	 -1	 |	 	 	 	 	 	 	 1	 |	 〇〇勉強会
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 -2	 |	 △△勉強会
(3	 rows)
testdb=#	 SELECT	 *	 FROM	 entries;
	 entry_id	 |	 user_id	 |	 event_id	 |	 	 	 	 stat	 	 	 	 |	 	 message	 	 	 
----------+---------+----------+------------+------------
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 	 2	 |	 キャンセル	 |	 ごめんね
	 	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 -1	 |	 参加	 	 	 	 	 	 	 |	 いち
	 	 	 	 	 	 	 	 4	 |	 	 	 	 	 	 -2	 |	 	 	 	 	 	 	 	 2	 |	 参加	 	 	 	 	 	 	 |	 にばん
	 	 	 	 	 	 	 	 5	 |	 	 	 	 	 	 -2	 |	 	 	 	 	 	 	 	 3	 |	 参加	 	 	 	 	 	 	 |	 よろしく
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 -2	 |	 	 	 	 	 	 	 -1	 |	 参加	 	 	 	 	 	 	 |	 参加します
(5	 rows)
--	 ちなみに、物理削除するとON	 DELETE	 CASCADEで連鎖削除される
testdb=#	 DELETE	 FROM	 users	 WHERE	 user_id	 =	 1;
DELETE	 1

testdb=#	 SELECT	 *	 FROM	 users;
	 user_id	 |	 name	 |	 pass	 
---------+------+------
	 	 	 	 	 	 -2	 |	 ken	 	 |	 xxx
(1	 row)

testdb=#	 SELECT	 *	 FROM	 events;
	 event_id	 |	 user_id	 |	 	 	 name	 	 	 
----------+---------+----------
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 -2	 |	 △△勉強会
(1	 row)

testdb=#	 SELECT	 *	 FROM	 entries;
	 entry_id	 |	 user_id	 |	 event_id	 |	 stat	 |	 message	 	 
----------+---------+----------+------+----------
	 	 	 	 	 	 	 	 5	 |	 	 	 	 	 	 -2	 |	 	 	 	 	 	 	 	 3	 |	 参加	 |	 よろしく
(1	 row)
--	 ユーザテーブルを作成する                     --	 エントリーテーブルを作成する
CREATE	 TABLE	 users	 (              CREATE	 TABLE	 entries	 (
	 	 user_id	 SERIAL	 NOT	 NULL,      	 	 entry_id	 SERIAL	 	 NOT	 NULL,
	 	 name	 	 	 	 TEXT,                	 	 user_id	 	 INTEGER	 NOT	 NULL,
	 	 pass	 	 	 	 TEXT,                	 	 event_id	 INTEGER	 NOT	 NULL,
	 	 PRIMARY	 KEY(user_id)            	 	 stat	 	 	 	 	 TEXT	 NOT	 NULL,
);                                   	 	 message	 	 TEXT,
                                     	 	 PRIMARY	 KEY(entry_id),
--	 イベントテーブルを作成する                    	 	 FOREIGN	 KEY(user_id)
CREATE	 TABLE	 events	 (             	 	 	 	 REFERENCES	 users(user_id)
	 	 event_id	 SERIAL	 	 NOT	 NULL,   	 	 	 	 	 	 ON	 DELETE	 CASCADE
	 	 user_id	 	 INTEGER	 NOT	 NULL,   	 	 	 	 	 	 ON	 UPDATE	 CASCADE,
	 	 name	 	 	 	 	 TEXT,              	 	 FOREIGN	 KEY(event_id)
	 	 PRIMARY	 KEY(event_id),          	 	 	 	 REFERENCES	 events(event_id)
	 	 FOREIGN	 KEY(user_id)            	 	 	 	 	 	 ON	 DELETE	 CASCADE
	 	 	 	 REFERENCES	 users(user_id)   	 	 	 	 	 	 ON	 UPDATE	 CASCADE,
	 	 	 	 	 	 ON	 DELETE	 CASCADE      	 	 UNIQUE(user_id,	 event_id)
	 	 	 	 	 	 ON	 UPDATE	 CASCADE      );
);
--	 部分インデックスではなくユニークになる
CREATE	 UNIQUE	 INDEX	 unq_users_name	 ON	 users	 (name);
--	 削除されたユーザの保存先を作成する
CREATE	 TABLE	 deleted_users	 (
	 	 user_id	 SERIAL	 NOT	 NULL,
	 	 name	 	 	 	 TEXT,
	 	 pass	 	 	 	 TEXT
);

--	 削除されたイベントの保存先を作成する
CREATE	 TABLE	 deleted_events	 (
	 	 event_id	 SERIAL	 	 NOT	 NULL,
	 	 user_id	 	 INTEGER	 NOT	 NULL,
	 	 name	 	 	 	 	 TEXT
);

--	 削除されたエントリの保存先を作成する
CREATE	 TABLE	 deleted_entries	 (
	 	 entry_id	 SERIAL	 	 NOT	 NULL,
	 	 user_id	 	 INTEGER	 NOT	 NULL,
	 	 event_id	 INTEGER	 NOT	 NULL,
	 	 stat	 	 	 	 	 TEXT	 NOT	 NULL,
	 	 message	 	 TEXT
);
--	 DELETE実行時に実行するFUNCTIONを定義する
CREATE	 OR	 REPLACE	 FUNCTION	 process_deleted()	 RETURNS	 TRIGGER	 AS	 $$
	 	 	 	 BEGIN
	 	 	 	 	 	 	 	 IF	 (TG_OP	 =	 'DELETE')	 THEN
	 	 	 	 	 	 	 	 	 	 	 	 EXECUTE	 'INSERT	 INTO	 deleted_'	 ||	 
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 TG_RELNAME	 ||	 '	 VALUES(($1).*)'	 USING	 OLD;
	 	 	 	 	 	 	 	 	 	 	 	 RETURN	 OLD;
	 	 	 	 	 	 	 	 END	 IF;
	 	 	 	 	 	 	 	 RETURN	 NULL;
	 	 	 	 END;
$$	 LANGUAGE	 plpgsql;
--	 DELETE時に実行するTRIGGERを仕掛ける
CREATE	 TRIGGER	 trigger_users_deleted
AFTER	 DELETE	 ON	 users
	 	 	 	 FOR	 EACH	 ROW	 EXECUTE	 PROCEDURE	 process_deleted();

CREATE	 TRIGGER	 trigger_events_deleted
AFTER	 DELETE	 ON	 events
	 	 	 	 FOR	 EACH	 ROW	 EXECUTE	 PROCEDURE	 process_deleted();

CREATE	 TRIGGER	 trigger_entries_deleted
AFTER	 DELETE	 ON	 entries
	 	 	 	 FOR	 EACH	 ROW	 EXECUTE	 PROCEDURE	 process_deleted();
--	 テストデータを投入する
INSERT	 INTO	 users	 (name,	 pass)	 VALUES	 ('ryu',	 'xxx');
INSERT	 INTO	 users	 (name,	 pass)	 VALUES	 ('ken',	 'xxx');

INSERT	 INTO	 events	 (user_id,	 name)	 VALUES	 (1,	 '〇〇勉強会');
INSERT	 INTO	 events	 (user_id,	 name)	 VALUES	 (1,	 '××勉強会');
INSERT	 INTO	 events	 (user_id,	 name)	 VALUES	 (2,	 '△△勉強会');

INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)
	 	 	 	 VALUES	 (1,	 1,	 '参加',	 'いち');
INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)	 
	 	 	 	 VALUES	 (1,	 2,	 '参加',	 '参加します');
INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)	 
	 	 	 	 VALUES	 (2,	 1,	 'キャンセル',	 'ごめんね');
INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)
	 	 	 	 VALUES	 (2,	 2,	 '参加',	 'にばん');
INSERT	 INTO	 entries	 (event_id,	 user_id,	 stat,	 message)
	 	 	 	 VALUES	 (3,	 2,	 '参加',	 'よろしく');
--	 テストデータを確認する
testdb=#	 SELECT	 *	 FROM	 users;
	 user_id	 |	 name	 |	 pass	 
---------+------+------
	 	 	 	 	 	 	 1	 |	 ryu	 	 |	 xxx
	 	 	 	 	 	 	 2	 |	 ken	 	 |	 xxx
(2	 rows)
testdb=#	 SELECT	 *	 FROM	 events;
	 event_id	 |	 user_id	 |	 	 	 	 name	 	 	 	 
----------+---------+------------
	 	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 1	 |	 〇〇勉強会
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 1	 |	 ××勉強会
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 2	 |	 △△勉強会
(3	 rows)
testdb=#	 SELECT	 *	 FROM	 entries;;
	 entry_id	 |	 user_id	 |	 event_id	 |	 	 	 	 stat	 	 	 	 |	 	 message	 	 	 
----------+---------+----------+------------+------------
	 	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 	 1	 |	 参加	 	 	 	 	 	 	 |	 いち
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 1	 |	 参加	 	 	 	 	 	 	 |	 参加します
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 	 2	 |	 キャンセル	 |	 ごめんね
	 	 	 	 	 	 	 	 4	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 2	 |	 参加	 	 	 	 	 	 	 |	 にばん
	 	 	 	 	 	 	 	 5	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 3	 |	 参加	 	 	 	 	 	 	 |	 よろしく
(5	 rows)
--	 削除されたデータの保存先は空
testdb=#	 SELECT	 *	 FROM	 deleted_users;
	 user_id	 |	 name	 |	 pass	 
---------+------+------
(0	 rows)

testdb=#	 SELECT	 *	 FROM	 deleted_events;
	 event_id	 |	 user_id	 |	 name	 
----------+---------+------
(0	 rows)

testdb=#	 SELECT	 *	 FROM	 deleted_entries;
	 entry_id	 |	 user_id	 |	 event_id	 |	 stat	 |	 message	 
----------+---------+----------+------+---------
(0	 rows)
--	 ユーザを削除してみる
DELETE	 FROM	 users	 WHERE	 user_id	 =	 1;
--	 他の関連するレコードも連鎖的に削除されている
testdb2=#	 SELECT	 *	 FROM	 users;
	 user_id	 |	 name	 |	 pass	 
---------+------+------
	 	 	 	 	 	 	 2	 |	 ken	 	 |	 xxx
(1	 row)

testdb2=#	 SELECT	 *	 FROM	 events;
	 event_id	 |	 user_id	 |	 	 	 name	 	 	 
----------+---------+----------
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 2	 |	 △△勉強会
(1	 row)

testdb2=#	 SELECT	 *	 FROM	 entries;
	 entry_id	 |	 user_id	 |	 event_id	 |	 stat	 |	 message	 	 
----------+---------+----------+------+----------
	 	 	 	 	 	 	 	 5	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 3	 |	 参加	 |	 よろしく
(1	 row)
--	 連鎖的に削除されたレコードは保存用のテーブルに退避されている
testdb2=#	 SELECT	 *	 FROM	 deleted_users;
	 user_id	 |	 name	 |	 pass	 
---------+------+------
	 	 	 	 	 	 	 1	 |	 ryu	 	 |	 xxx
(1	 row)

testdb2=#	 SELECT	 *	 FROM	 deleted_events;
	 event_id	 |	 user_id	 |	 	 	 	 name	 	 	 	 
----------+---------+------------
	 	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 1	 |	 〇〇勉強会
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 1	 |	 ××勉強会
(2	 rows)

testdb2=#	 SELECT	 *	 FROM	 deleted_entries;
	 entry_id	 |	 user_id	 |	 event_id	 |	 	 	 	 stat	 	 	 	 |	 	 message	 	 	 
----------+---------+----------+------------+------------
	 	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 	 1	 |	 参加	 	 	 	 	 	 	 |	 いち
	 	 	 	 	 	 	 	 3	 |	 	 	 	 	 	 	 1	 |	 	 	 	 	 	 	 	 2	 |	 キャンセル	 |	 ごめんね
	 	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 1	 |	 参加	 	 	 	 	 	 	 |	 参加します
	 	 	 	 	 	 	 	 4	 |	 	 	 	 	 	 	 2	 |	 	 	 	 	 	 	 	 2	 |	 参加	 	 	 	 	 	 	 |	 にばん
(4	 rows)
CREATE	 TABLE	 emp	 (
	 	 	 	 empname	 	 	 	 	 	 	 	 	 	 	 text	 NOT	 NULL,
	 	 	 	 salary	 	 	 	 	 	 	 	 	 	 	 	 integer
);

CREATE	 TABLE	 emp_audit(
	 	 	 	 operation	 	 	 	 	 	 	 	 	 char(1)	 	 	 NOT	 NULL,
	 	 	 	 stamp	 	 	 	 	 	 	 	 	 	 	 	 	 timestamp	 NOT	 NULL,
	 	 	 	 userid	 	 	 	 	 	 	 	 	 	 	 	 text	 	 	 	 	 	 NOT	 NULL,
	 	 	 	 empname	 	 	 	 	 	 	 	 	 	 	 text	 	 	 	 	 	 NOT	 NULL,
	 	 	 	 salary	 integer
);

CREATE	 OR	 REPLACE	 FUNCTION	 process_emp_audit()	 RETURNS	 TRIGGER	 AS	 $emp_audit$
	 	 	 	 BEGIN
	 	 	 	 	 	 	 	 --
	 	 	 	 	 	 	 	 --	 Create	 a	 row	 in	 emp_audit	 to	 reflect	 the	 operation	 performed	 on	 emp,
	 	 	 	 	 	 	 	 --	 make	 use	 of	 the	 special	 variable	 TG_OP	 to	 work	 out	 the	 operation.
	 	 	 	 	 	 	 	 --
	 	 	 	 	 	 	 	 IF	 (TG_OP	 =	 'DELETE')	 THEN
	 	 	 	 	 	 	 	 	 	 	 	 INSERT	 INTO	 emp_audit	 SELECT	 'D',	 now(),	 user,	 OLD.*;
	 	 	 	 	 	 	 	 	 	 	 	 RETURN	 OLD;
	 	 	 	 	 	 	 	 ELSIF	 (TG_OP	 =	 'UPDATE')	 THEN
	 	 	 	 	 	 	 	 	 	 	 	 INSERT	 INTO	 emp_audit	 SELECT	 'U',	 now(),	 user,	 NEW.*;
	 	 	 	 	 	 	 	 	 	 	 	 RETURN	 NEW;
	 	 	 	 	 	 	 	 ELSIF	 (TG_OP	 =	 'INSERT')	 THEN
	 	 	 	 	 	 	 	 	 	 	 	 INSERT	 INTO	 emp_audit	 SELECT	 'I',	 now(),	 user,	 NEW.*;
	 	 	 	 	 	 	 	 	 	 	 	 RETURN	 NEW;
	 	 	 	 	 	 	 	 END	 IF;
	 	 	 	 	 	 	 	 RETURN	 NULL;	 --	 result	 is	 ignored	 since	 this	 is	 an	 AFTER	 trigger
	 	 	 	 END;
$emp_audit$	 LANGUAGE	 plpgsql;

CREATE	 TRIGGER	 emp_audit
AFTER	 INSERT	 OR	 UPDATE	 OR	 DELETE	 ON	 emp
	 	 	 	 FOR	 EACH	 ROW	 EXECUTE	 PROCEDURE	 process_emp_audit();

Weitere ähnliche Inhalte

Was ist angesagt?

MySQLアンチパターン
MySQLアンチパターンMySQLアンチパターン
MySQLアンチパターンyoku0825
 
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)Mikiya Okuno
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう増田 亨
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)AtCoder Inc.
 
(2017.6.9) Neo4jの可視化ライブラリまとめ
(2017.6.9) Neo4jの可視化ライブラリまとめ(2017.6.9) Neo4jの可視化ライブラリまとめ
(2017.6.9) Neo4jの可視化ライブラリまとめMitsutoshi Kiuchi
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方増田 亨
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門増田 亨
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
Fault, Error, Failure の違い
Fault, Error, Failure の違いFault, Error, Failure の違い
Fault, Error, Failure の違いMizuhiro Kaimai
 
SQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォークSQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォークke-m kamekoopa
 
ちいさなオブジェクトでドメインモデルを組み立てる
ちいさなオブジェクトでドメインモデルを組み立てるちいさなオブジェクトでドメインモデルを組み立てる
ちいさなオブジェクトでドメインモデルを組み立てる増田 亨
 
Ormとの付き合い方
Ormとの付き合い方Ormとの付き合い方
Ormとの付き合い方豊明 尾古
 
データモデリング入門-astah*を使って、TMの手法を使う-
データモデリング入門-astah*を使って、TMの手法を使う-データモデリング入門-astah*を使って、TMの手法を使う-
データモデリング入門-astah*を使って、TMの手法を使う-Koichi Inami
 
Rで計量時系列分析~CRANパッケージ総ざらい~
Rで計量時系列分析~CRANパッケージ総ざらい~ Rで計量時系列分析~CRANパッケージ総ざらい~
Rで計量時系列分析~CRANパッケージ総ざらい~ Takashi J OZAKI
 
カルマンフィルタ入門
カルマンフィルタ入門カルマンフィルタ入門
カルマンフィルタ入門Yasunori Nihei
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介Shinya Okano
 
採用スライド2022.pdf
採用スライド2022.pdf採用スライド2022.pdf
採用スライド2022.pdfAyumiYoanSato
 
Djangoフレームワークのユーザーモデルと認証
Djangoフレームワークのユーザーモデルと認証Djangoフレームワークのユーザーモデルと認証
Djangoフレームワークのユーザーモデルと認証Shinya Okano
 

Was ist angesagt? (20)

MySQLアンチパターン
MySQLアンチパターンMySQLアンチパターン
MySQLアンチパターン
 
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)
 
(2017.6.9) Neo4jの可視化ライブラリまとめ
(2017.6.9) Neo4jの可視化ライブラリまとめ(2017.6.9) Neo4jの可視化ライブラリまとめ
(2017.6.9) Neo4jの可視化ライブラリまとめ
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Fault, Error, Failure の違い
Fault, Error, Failure の違いFault, Error, Failure の違い
Fault, Error, Failure の違い
 
SQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォークSQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォーク
 
ちいさなオブジェクトでドメインモデルを組み立てる
ちいさなオブジェクトでドメインモデルを組み立てるちいさなオブジェクトでドメインモデルを組み立てる
ちいさなオブジェクトでドメインモデルを組み立てる
 
Ormとの付き合い方
Ormとの付き合い方Ormとの付き合い方
Ormとの付き合い方
 
データモデリング入門-astah*を使って、TMの手法を使う-
データモデリング入門-astah*を使って、TMの手法を使う-データモデリング入門-astah*を使って、TMの手法を使う-
データモデリング入門-astah*を使って、TMの手法を使う-
 
Java8でRDBMS作ったよ
Java8でRDBMS作ったよJava8でRDBMS作ったよ
Java8でRDBMS作ったよ
 
Rで計量時系列分析~CRANパッケージ総ざらい~
Rで計量時系列分析~CRANパッケージ総ざらい~ Rで計量時系列分析~CRANパッケージ総ざらい~
Rで計量時系列分析~CRANパッケージ総ざらい~
 
カルマンフィルタ入門
カルマンフィルタ入門カルマンフィルタ入門
カルマンフィルタ入門
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
採用スライド2022.pdf
採用スライド2022.pdf採用スライド2022.pdf
採用スライド2022.pdf
 
Djangoフレームワークのユーザーモデルと認証
Djangoフレームワークのユーザーモデルと認証Djangoフレームワークのユーザーモデルと認証
Djangoフレームワークのユーザーモデルと認証
 

Andere mochten auch

Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてkimukou_26 Kimukou
 
Building scalablewebapps
Building scalablewebappsBuilding scalablewebapps
Building scalablewebappsAyumu Aizawa
 
ソフトウェアパッケージベンダーのためのクラウドソリューション「SQL Anywhere OnDemand Edition」
ソフトウェアパッケージベンダーのためのクラウドソリューション「SQL Anywhere OnDemand Edition」ソフトウェアパッケージベンダーのためのクラウドソリューション「SQL Anywhere OnDemand Edition」
ソフトウェアパッケージベンダーのためのクラウドソリューション「SQL Anywhere OnDemand Edition」nisobe58
 
ngServer and-collaboratived-development-between-san-francisco-and-tokyo
ngServer and-collaboratived-development-between-san-francisco-and-tokyongServer and-collaboratived-development-between-san-francisco-and-tokyo
ngServer and-collaboratived-development-between-san-francisco-and-tokyoSatoshi Tanaka
 
17 E-5 震災とHackとクラウドと 亀渕分
17 E-5 震災とHackとクラウドと 亀渕分17 E-5 震災とHackとクラウドと 亀渕分
17 E-5 震災とHackとクラウドと 亀渕分Keiji Kamebuchi
 
アイデアを塩漬けにしない-世界中の人に手伝ってもらう方法-
アイデアを塩漬けにしない-世界中の人に手伝ってもらう方法-アイデアを塩漬けにしない-世界中の人に手伝ってもらう方法-
アイデアを塩漬けにしない-世界中の人に手伝ってもらう方法-nishio
 
Japan Developer Summit (jp) - Cloud Foundry, the Open Platform As A Service
Japan Developer Summit (jp) - Cloud Foundry, the Open Platform As A ServiceJapan Developer Summit (jp) - Cloud Foundry, the Open Platform As A Service
Japan Developer Summit (jp) - Cloud Foundry, the Open Platform As A ServicePatrick Chanezon
 
ngGoBuilder and collaborative development between San Francisco and Tokyo
ngGoBuilder and collaborative development between San Francisco and TokyongGoBuilder and collaborative development between San Francisco and Tokyo
ngGoBuilder and collaborative development between San Francisco and Tokyonotolab
 
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)Yuuki Namikawa
 
【17-E-3】 オンライン機械学習で実現する大規模データ処理
【17-E-3】 オンライン機械学習で実現する大規模データ処理【17-E-3】 オンライン機械学習で実現する大規模データ処理
【17-E-3】 オンライン機械学習で実現する大規模データ処理Developers Summit
 
Pursuit of happiness
Pursuit of happinessPursuit of happiness
Pursuit of happinessbioideology
 
Standing female nude’’
Standing female nude’’Standing female nude’’
Standing female nude’’may
 
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)Akihiro Kuwano
 
Ann Summers Cat 66 Slide Show
Ann Summers Cat 66 Slide ShowAnn Summers Cat 66 Slide Show
Ann Summers Cat 66 Slide ShowMargaret_R
 
17 A QuíMica Da Pele
17 A QuíMica Da Pele17 A QuíMica Da Pele
17 A QuíMica Da PeleClaudia Lage
 

Andere mochten auch (16)

Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用について
 
Building scalablewebapps
Building scalablewebappsBuilding scalablewebapps
Building scalablewebapps
 
ソフトウェアパッケージベンダーのためのクラウドソリューション「SQL Anywhere OnDemand Edition」
ソフトウェアパッケージベンダーのためのクラウドソリューション「SQL Anywhere OnDemand Edition」ソフトウェアパッケージベンダーのためのクラウドソリューション「SQL Anywhere OnDemand Edition」
ソフトウェアパッケージベンダーのためのクラウドソリューション「SQL Anywhere OnDemand Edition」
 
ngServer and-collaboratived-development-between-san-francisco-and-tokyo
ngServer and-collaboratived-development-between-san-francisco-and-tokyongServer and-collaboratived-development-between-san-francisco-and-tokyo
ngServer and-collaboratived-development-between-san-francisco-and-tokyo
 
17 E-5 震災とHackとクラウドと 亀渕分
17 E-5 震災とHackとクラウドと 亀渕分17 E-5 震災とHackとクラウドと 亀渕分
17 E-5 震災とHackとクラウドと 亀渕分
 
アイデアを塩漬けにしない-世界中の人に手伝ってもらう方法-
アイデアを塩漬けにしない-世界中の人に手伝ってもらう方法-アイデアを塩漬けにしない-世界中の人に手伝ってもらう方法-
アイデアを塩漬けにしない-世界中の人に手伝ってもらう方法-
 
Japan Developer Summit (jp) - Cloud Foundry, the Open Platform As A Service
Japan Developer Summit (jp) - Cloud Foundry, the Open Platform As A ServiceJapan Developer Summit (jp) - Cloud Foundry, the Open Platform As A Service
Japan Developer Summit (jp) - Cloud Foundry, the Open Platform As A Service
 
ngGoBuilder and collaborative development between San Francisco and Tokyo
ngGoBuilder and collaborative development between San Francisco and TokyongGoBuilder and collaborative development between San Francisco and Tokyo
ngGoBuilder and collaborative development between San Francisco and Tokyo
 
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (後編)
 
【17-E-3】 オンライン機械学習で実現する大規模データ処理
【17-E-3】 オンライン機械学習で実現する大規模データ処理【17-E-3】 オンライン機械学習で実現する大規模データ処理
【17-E-3】 オンライン機械学習で実現する大規模データ処理
 
Pursuit of happiness
Pursuit of happinessPursuit of happiness
Pursuit of happiness
 
Standing female nude’’
Standing female nude’’Standing female nude’’
Standing female nude’’
 
Fuck PPT
Fuck PPTFuck PPT
Fuck PPT
 
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)
大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~ (前編)
 
Ann Summers Cat 66 Slide Show
Ann Summers Cat 66 Slide ShowAnn Summers Cat 66 Slide Show
Ann Summers Cat 66 Slide Show
 
17 A QuíMica Da Pele
17 A QuíMica Da Pele17 A QuíMica Da Pele
17 A QuíMica Da Pele
 

Ähnlich wie 削除フラグのはなし

20181110 fok2018-pg-extension
20181110 fok2018-pg-extension20181110 fok2018-pg-extension
20181110 fok2018-pg-extensionToshi Harada
 
5 古雷my sql源碼與資料庫規範
5 古雷my sql源碼與資料庫規範5 古雷my sql源碼與資料庫規範
5 古雷my sql源碼與資料庫規範Ivan Tu
 
20190119 aws-study-pg-extension
20190119 aws-study-pg-extension20190119 aws-study-pg-extension
20190119 aws-study-pg-extensionToshi Harada
 
MySQLとPostgreSQLの基本的な実行プラン比較
MySQLとPostgreSQLの基本的な実行プラン比較MySQLとPostgreSQLの基本的な実行プラン比較
MySQLとPostgreSQLの基本的な実行プラン比較Shinya Sugiyama
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~Nobuhisa Koizumi
 
03 kueripahuomansuchiyuninguno shou_fa_
03 kueripahuomansuchiyuninguno shou_fa_03 kueripahuomansuchiyuninguno shou_fa_
03 kueripahuomansuchiyuninguno shou_fa_Kaito Tonooka
 

Ähnlich wie 削除フラグのはなし (7)

20181110 fok2018-pg-extension
20181110 fok2018-pg-extension20181110 fok2018-pg-extension
20181110 fok2018-pg-extension
 
5 古雷my sql源碼與資料庫規範
5 古雷my sql源碼與資料庫規範5 古雷my sql源碼與資料庫規範
5 古雷my sql源碼與資料庫規範
 
20190119 aws-study-pg-extension
20190119 aws-study-pg-extension20190119 aws-study-pg-extension
20190119 aws-study-pg-extension
 
MySQLとPostgreSQLの基本的な実行プラン比較
MySQLとPostgreSQLの基本的な実行プラン比較MySQLとPostgreSQLの基本的な実行プラン比較
MySQLとPostgreSQLの基本的な実行プラン比較
 
メッチャ役に立つauto_incrementの話
メッチャ役に立つauto_incrementの話メッチャ役に立つauto_incrementの話
メッチャ役に立つauto_incrementの話
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
03 kueripahuomansuchiyuninguno shou_fa_
03 kueripahuomansuchiyuninguno shou_fa_03 kueripahuomansuchiyuninguno shou_fa_
03 kueripahuomansuchiyuninguno shou_fa_
 

Kürzlich hochgeladen

【株式会社オプティマインド】会社紹介資料_2024年4月11日更新(採用資料).pdf
【株式会社オプティマインド】会社紹介資料_2024年4月11日更新(採用資料).pdf【株式会社オプティマインド】会社紹介資料_2024年4月11日更新(採用資料).pdf
【株式会社オプティマインド】会社紹介資料_2024年4月11日更新(採用資料).pdf株式会社オプティマインド
 
株式会社ベクトル総研会社概要 Vector Research Institute (VRI) Corporate Profile
株式会社ベクトル総研会社概要 Vector Research Institute (VRI) Corporate Profile株式会社ベクトル総研会社概要 Vector Research Institute (VRI) Corporate Profile
株式会社ベクトル総研会社概要 Vector Research Institute (VRI) Corporate Profilevrihomepage
 
株式会社デジタルフォルン_会社説明資料~カルチャー~         2024年版
株式会社デジタルフォルン_会社説明資料~カルチャー~         2024年版株式会社デジタルフォルン_会社説明資料~カルチャー~         2024年版
株式会社デジタルフォルン_会社説明資料~カルチャー~         2024年版DIGITAL VORN
 
令和5年度_サステナブルツーリズムセミナー_ビジュアルレポート(公開用).pdf
令和5年度_サステナブルツーリズムセミナー_ビジュアルレポート(公開用).pdf令和5年度_サステナブルツーリズムセミナー_ビジュアルレポート(公開用).pdf
令和5年度_サステナブルツーリズムセミナー_ビジュアルレポート(公開用).pdfjun_suto
 
20240318_case___________________________
20240318_case___________________________20240318_case___________________________
20240318_case___________________________i Smart Technologies
 
Sportip, Inc. Company Deck 2024|株式会社Sportip紹介資料
Sportip, Inc. Company Deck 2024|株式会社Sportip紹介資料Sportip, Inc. Company Deck 2024|株式会社Sportip紹介資料
Sportip, Inc. Company Deck 2024|株式会社Sportip紹介資料ssuser5a38bf
 
「育て」「動かし」「評価する」PRMツール。「PartnerProp」パートナープロップサービス資料
「育て」「動かし」「評価する」PRMツール。「PartnerProp」パートナープロップサービス資料「育て」「動かし」「評価する」PRMツール。「PartnerProp」パートナープロップサービス資料
「育て」「動かし」「評価する」PRMツール。「PartnerProp」パートナープロップサービス資料inoue13
 
株式会社デジタルフォルン_会社説明資料~その他の働く環境~         2024年版
株式会社デジタルフォルン_会社説明資料~その他の働く環境~         2024年版株式会社デジタルフォルン_会社説明資料~その他の働く環境~         2024年版
株式会社デジタルフォルン_会社説明資料~その他の働く環境~         2024年版DIGITAL VORN
 
株式会社デジタルフォルン_会社説明資料~仕事内容~         2024年版
株式会社デジタルフォルン_会社説明資料~仕事内容~         2024年版株式会社デジタルフォルン_会社説明資料~仕事内容~         2024年版
株式会社デジタルフォルン_会社説明資料~仕事内容~         2024年版DIGITAL VORN
 
HRMOS(ハーモス)タレントマネジメント_ご紹介資料_Saleshub掲載用
HRMOS(ハーモス)タレントマネジメント_ご紹介資料_Saleshub掲載用HRMOS(ハーモス)タレントマネジメント_ご紹介資料_Saleshub掲載用
HRMOS(ハーモス)タレントマネジメント_ご紹介資料_Saleshub掲載用wataruhonda3
 
20240209_case___________________________
20240209_case___________________________20240209_case___________________________
20240209_case___________________________i Smart Technologies
 
【株式会社オプティマインド】会社紹介資料(2024年04月更新)_中途採用.pdf
【株式会社オプティマインド】会社紹介資料(2024年04月更新)_中途採用.pdf【株式会社オプティマインド】会社紹介資料(2024年04月更新)_中途採用.pdf
【株式会社オプティマインド】会社紹介資料(2024年04月更新)_中途採用.pdf株式会社オプティマインド
 
20240319_case___________________________
20240319_case___________________________20240319_case___________________________
20240319_case___________________________i Smart Technologies
 
株式会社デジタルフォルン_会社説明資料~事業内容~         2024年版
株式会社デジタルフォルン_会社説明資料~事業内容~         2024年版株式会社デジタルフォルン_会社説明資料~事業内容~         2024年版
株式会社デジタルフォルン_会社説明資料~事業内容~         2024年版DIGITAL VORN
 
ROMS_recruting_deck_for_website_20240322.pdf
ROMS_recruting_deck_for_website_20240322.pdfROMS_recruting_deck_for_website_20240322.pdf
ROMS_recruting_deck_for_website_20240322.pdfhirokisawa3
 

Kürzlich hochgeladen (16)

【株式会社オプティマインド】会社紹介資料_2024年4月11日更新(採用資料).pdf
【株式会社オプティマインド】会社紹介資料_2024年4月11日更新(採用資料).pdf【株式会社オプティマインド】会社紹介資料_2024年4月11日更新(採用資料).pdf
【株式会社オプティマインド】会社紹介資料_2024年4月11日更新(採用資料).pdf
 
株式会社ベクトル総研会社概要 Vector Research Institute (VRI) Corporate Profile
株式会社ベクトル総研会社概要 Vector Research Institute (VRI) Corporate Profile株式会社ベクトル総研会社概要 Vector Research Institute (VRI) Corporate Profile
株式会社ベクトル総研会社概要 Vector Research Institute (VRI) Corporate Profile
 
株式会社デジタルフォルン_会社説明資料~カルチャー~         2024年版
株式会社デジタルフォルン_会社説明資料~カルチャー~         2024年版株式会社デジタルフォルン_会社説明資料~カルチャー~         2024年版
株式会社デジタルフォルン_会社説明資料~カルチャー~         2024年版
 
令和5年度_サステナブルツーリズムセミナー_ビジュアルレポート(公開用).pdf
令和5年度_サステナブルツーリズムセミナー_ビジュアルレポート(公開用).pdf令和5年度_サステナブルツーリズムセミナー_ビジュアルレポート(公開用).pdf
令和5年度_サステナブルツーリズムセミナー_ビジュアルレポート(公開用).pdf
 
20240318_case___________________________
20240318_case___________________________20240318_case___________________________
20240318_case___________________________
 
Sportip, Inc. Company Deck 2024|株式会社Sportip紹介資料
Sportip, Inc. Company Deck 2024|株式会社Sportip紹介資料Sportip, Inc. Company Deck 2024|株式会社Sportip紹介資料
Sportip, Inc. Company Deck 2024|株式会社Sportip紹介資料
 
「育て」「動かし」「評価する」PRMツール。「PartnerProp」パートナープロップサービス資料
「育て」「動かし」「評価する」PRMツール。「PartnerProp」パートナープロップサービス資料「育て」「動かし」「評価する」PRMツール。「PartnerProp」パートナープロップサービス資料
「育て」「動かし」「評価する」PRMツール。「PartnerProp」パートナープロップサービス資料
 
株式会社デジタルフォルン_会社説明資料~その他の働く環境~         2024年版
株式会社デジタルフォルン_会社説明資料~その他の働く環境~         2024年版株式会社デジタルフォルン_会社説明資料~その他の働く環境~         2024年版
株式会社デジタルフォルン_会社説明資料~その他の働く環境~         2024年版
 
株式会社デジタルフォルン_会社説明資料~仕事内容~         2024年版
株式会社デジタルフォルン_会社説明資料~仕事内容~         2024年版株式会社デジタルフォルン_会社説明資料~仕事内容~         2024年版
株式会社デジタルフォルン_会社説明資料~仕事内容~         2024年版
 
HRMOS(ハーモス)タレントマネジメント_ご紹介資料_Saleshub掲載用
HRMOS(ハーモス)タレントマネジメント_ご紹介資料_Saleshub掲載用HRMOS(ハーモス)タレントマネジメント_ご紹介資料_Saleshub掲載用
HRMOS(ハーモス)タレントマネジメント_ご紹介資料_Saleshub掲載用
 
20240209_case___________________________
20240209_case___________________________20240209_case___________________________
20240209_case___________________________
 
【株式会社オプティマインド】会社紹介資料(2024年04月更新)_中途採用.pdf
【株式会社オプティマインド】会社紹介資料(2024年04月更新)_中途採用.pdf【株式会社オプティマインド】会社紹介資料(2024年04月更新)_中途採用.pdf
【株式会社オプティマインド】会社紹介資料(2024年04月更新)_中途採用.pdf
 
20240319_case___________________________
20240319_case___________________________20240319_case___________________________
20240319_case___________________________
 
Japan IT Week 2024 Brochure by 47Billion
Japan IT Week 2024 Brochure by 47BillionJapan IT Week 2024 Brochure by 47Billion
Japan IT Week 2024 Brochure by 47Billion
 
株式会社デジタルフォルン_会社説明資料~事業内容~         2024年版
株式会社デジタルフォルン_会社説明資料~事業内容~         2024年版株式会社デジタルフォルン_会社説明資料~事業内容~         2024年版
株式会社デジタルフォルン_会社説明資料~事業内容~         2024年版
 
ROMS_recruting_deck_for_website_20240322.pdf
ROMS_recruting_deck_for_website_20240322.pdfROMS_recruting_deck_for_website_20240322.pdf
ROMS_recruting_deck_for_website_20240322.pdf
 

削除フラグのはなし

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6. id name pass is_deleted 1 ryu xxx FALSE 2 ken xxx FALSE 3 honda xxx TRUE
  • 7.
  • 8. id name pass is_deleted 1 ryu xxx FALSE 2 ken xxx FALSE 3 honda xxx TRUE 3 honda xxx FALSE
  • 9.
  • 10. WHERE is_deleted = false WHERE is_deleted = false WHERE is_deleted = false
  • 11. DELETE FROM users WHERE id = 2; UPDATE user SET is_update = true WHERE id = 2;
  • 12.
  • 13.
  • 14.
  • 15.
  • 16. id name pass is_deleted 1 ryu xxx TRUE 2 ryu xxx TRUE 3 ryu xxx FALSE 4 ryu xxx FALSE
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30. id name pass is_deleted 1 ryu xxx TRUE 2 ryu xxx TRUE 3 ryu xxx FALSE 4 ryu xxx FALSE
  • 31. -- CREATE TABLE users ( id SERIAL PRIMARY KEY, name TEXT, pass TEXT, is_deleted BOOL DEFAULT false ); -- CREATE UNIQUE INDEX users_valid_constraint ON users (name) WHERE NOT is_deleted;
  • 32.
  • 33. -- テーブルを作成する CREATE TABLE users ( id SERIAL PRIMARY KEY, name TEXT, pass TEXT, is_deleted BOOL DEFAULT false ); -- 一意な部分インデックスを張る CREATE UNIQUE INDEX users_valid_constraint ON users (name) WHERE NOT is_deleted;
  • 34. -- ryuを登録する testdb=# INSERT INTO users (name, pass, is_deleted) testdb-# VALUES ('ryu', 'xxx', false); INSERT 0 1 -- 登録したデータを確認 testdb=# SELECT * FROM users; id | name | pass | is_deleted ----+------+------+------------ 1 | ryu | xxx | f (1 row)
  • 35. -- 更にもう一件重複するryuを登録する testdb=# INSERT INTO users (name, pass, is_deleted) testdb-# VALUES ('ryu', 'xxx', false); ERROR: duplicate key value violates unique constraint "users_valid_constraint" DETAIL: Key (name)=(ryu) already exists.
  • 36. -- 削除フラグを立ててryuを削除したことにする testdb=# UPDATE users SET is_deleted = true testdb-# WHERE id = 1; UPDATE 1 -- ryuが論理削除されたことを確認 testdb=# SELECT * FROM users; id | name | pass | is_deleted ----+------+------+------------ 1 | ryu | xxx | t (1 row)
  • 37. -- ryuは削除されているのでryuを登録する testdb=# INSERT INTO users (name, pass, is_deleted) testdb-# VALUES ('ryu', 'xxx', false); INSERT 0 1 -- 登録したデータを確認する testdb=# SELECT * FROM users; id | name | pass | is_deleted ----+------+------+------------ 1 | ryu | xxx | t 3 | ryu | xxx | f (2 rows)
  • 38. -- 削除フラグを戻して削除したryuを復活させる testdb=# UPDATE users SET is_deleted = false testdb-# WHERE id = 1; ERROR: duplicate key value violates unique constraint "users_valid_constraint" DETAIL: Key (name)=(ryu) already exists.
  • 39. -- 現在のデータを確認する testdb=# SELECT * FROM users; id | name | pass | is_deleted ----+------+------+------------ 1 | ryu | xxx | t 3 | ryu | xxx | f (2 rows) -- 削除されていない方のryuを論理削除する testdb=# UPDATE users SET is_deleted = true testdb-# WHERE id = 3; -- 論理削除されたryuは2件あることを確認 testdb=# SELECT * FROM users; id | name | pass | is_deleted ----+------+------+------------ 1 | ryu | xxx | t 3 | ryu | xxx | t (2 rows)
  • 40.
  • 41.
  • 42.
  • 45.
  • 46. -- ユーザテーブルを作成する -- エントリーテーブルを作成する CREATE TABLE users ( CREATE TABLE entries ( user_id SERIAL NOT NULL, entry_id SERIAL NOT NULL, name TEXT, user_id INTEGER NOT NULL, pass TEXT, event_id INTEGER NOT NULL, PRIMARY KEY(user_id) stat TEXT NOT NULL, ); message TEXT, PRIMARY KEY(entry_id), -- イベントテーブルを作成する FOREIGN KEY(user_id) CREATE TABLE events ( REFERENCES users(user_id) event_id SERIAL NOT NULL, ON DELETE CASCADE user_id INTEGER NOT NULL, ON UPDATE CASCADE, name TEXT, FOREIGN KEY(event_id) PRIMARY KEY(event_id), REFERENCES events(event_id) FOREIGN KEY(user_id) ON DELETE CASCADE REFERENCES users(user_id) ON UPDATE CASCADE, ON DELETE CASCADE UNIQUE(user_id, event_id) ON UPDATE CASCADE ); );
  • 47. -- 一意な部分インデックスを張る(IDを利用) CREATE UNIQUE INDEX users_valid_constraint ON users (name) WHERE 0 < user_id;
  • 48. -- テストデータを投入する INSERT INTO users (name, pass) VALUES ('ryu', 'xxx'); INSERT INTO users (name, pass) VALUES ('ken', 'xxx'); INSERT INTO events (user_id, name) VALUES (1, '〇〇勉強会'); INSERT INTO events (user_id, name) VALUES (1, '××勉強会'); INSERT INTO events (user_id, name) VALUES (2, '△△勉強会'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (1, 1, '参加', 'いち'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (1, 2, '参加', '参加します'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (2, 1, 'キャンセル', 'ごめんね'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (2, 2, '参加', 'にばん'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (3, 2, '参加', 'よろしく');
  • 49. -- テストデータを確認する testdb=# SELECT * FROM users; user_id | name | pass ---------+------+------ 1 | ryu | xxx 2 | ken | xxx (2 rows) testdb=# SELECT * FROM events; event_id | user_id | name ----------+---------+------------ 1 | 1 | 〇〇勉強会 2 | 1 | ××勉強会 3 | 2 | △△勉強会 (3 rows) testdb=# SELECT * FROM entries;; entry_id | user_id | event_id | stat | message ----------+---------+----------+------------+------------ 1 | 1 | 1 | 参加 | いち 2 | 2 | 1 | 参加 | 参加します 3 | 1 | 2 | キャンセル | ごめんね 4 | 2 | 2 | 参加 | にばん 5 | 2 | 3 | 参加 | よろしく (5 rows)
  • 50. -- イベントを論理削除する UPDATE events SET event_id = event_id * -1 WHERE event_id = 1;
  • 51. -- 参照しているテーブルを確認する testdb=# SELECT * FROM users; user_id | name | pass ---------+------+------ 1 | ryu | xxx 2 | ken | xxx (2 rows) testdb=# SELECT * FROM events; event_id | user_id | name ----------+---------+------------ 2 | 1 | ××勉強会 3 | 2 | △△勉強会 -1 | 1 | 〇〇勉強会 (3 rows) testdb=# SELECT * FROM entries; entry_id | user_id | event_id | stat | message ----------+---------+----------+------------+------------ 3 | 1 | 2 | キャンセル | ごめんね 4 | 2 | 2 | 参加 | にばん 5 | 2 | 3 | 参加 | よろしく 1 | 1 | -1 | 参加 | いち 2 | 2 | -1 | 参加 | 参加します (5 rows)
  • 52. -- ユーザを論理削除する UPDATE users SET user_id = user_id * -1 WHERE user_id = 2;
  • 53. -- 参照しているテーブルを確認する testdb=# SELECT * FROM users; user_id | name | pass ---------+------+------ 1 | ryu | xxx -2 | ken | xxx (2 rows) testdb=# SELECT * FROM events; event_id | user_id | name ----------+---------+------------ 2 | 1 | ××勉強会 -1 | 1 | 〇〇勉強会 3 | -2 | △△勉強会 (3 rows) testdb=# SELECT * FROM entries; entry_id | user_id | event_id | stat | message ----------+---------+----------+------------+------------ 3 | 1 | 2 | キャンセル | ごめんね 1 | 1 | -1 | 参加 | いち 4 | -2 | 2 | 参加 | にばん 5 | -2 | 3 | 参加 | よろしく 2 | -2 | -1 | 参加 | 参加します (5 rows)
  • 54. -- ちなみに、物理削除するとON DELETE CASCADEで連鎖削除される testdb=# DELETE FROM users WHERE user_id = 1; DELETE 1 testdb=# SELECT * FROM users; user_id | name | pass ---------+------+------ -2 | ken | xxx (1 row) testdb=# SELECT * FROM events; event_id | user_id | name ----------+---------+---------- 3 | -2 | △△勉強会 (1 row) testdb=# SELECT * FROM entries; entry_id | user_id | event_id | stat | message ----------+---------+----------+------+---------- 5 | -2 | 3 | 参加 | よろしく (1 row)
  • 55.
  • 56.
  • 57.
  • 58.
  • 59. -- ユーザテーブルを作成する -- エントリーテーブルを作成する CREATE TABLE users ( CREATE TABLE entries ( user_id SERIAL NOT NULL, entry_id SERIAL NOT NULL, name TEXT, user_id INTEGER NOT NULL, pass TEXT, event_id INTEGER NOT NULL, PRIMARY KEY(user_id) stat TEXT NOT NULL, ); message TEXT, PRIMARY KEY(entry_id), -- イベントテーブルを作成する FOREIGN KEY(user_id) CREATE TABLE events ( REFERENCES users(user_id) event_id SERIAL NOT NULL, ON DELETE CASCADE user_id INTEGER NOT NULL, ON UPDATE CASCADE, name TEXT, FOREIGN KEY(event_id) PRIMARY KEY(event_id), REFERENCES events(event_id) FOREIGN KEY(user_id) ON DELETE CASCADE REFERENCES users(user_id) ON UPDATE CASCADE, ON DELETE CASCADE UNIQUE(user_id, event_id) ON UPDATE CASCADE ); );
  • 61. -- 削除されたユーザの保存先を作成する CREATE TABLE deleted_users ( user_id SERIAL NOT NULL, name TEXT, pass TEXT ); -- 削除されたイベントの保存先を作成する CREATE TABLE deleted_events ( event_id SERIAL NOT NULL, user_id INTEGER NOT NULL, name TEXT ); -- 削除されたエントリの保存先を作成する CREATE TABLE deleted_entries ( entry_id SERIAL NOT NULL, user_id INTEGER NOT NULL, event_id INTEGER NOT NULL, stat TEXT NOT NULL, message TEXT );
  • 62. -- DELETE実行時に実行するFUNCTIONを定義する CREATE OR REPLACE FUNCTION process_deleted() RETURNS TRIGGER AS $$ BEGIN IF (TG_OP = 'DELETE') THEN EXECUTE 'INSERT INTO deleted_' || TG_RELNAME || ' VALUES(($1).*)' USING OLD; RETURN OLD; END IF; RETURN NULL; END; $$ LANGUAGE plpgsql;
  • 63. -- DELETE時に実行するTRIGGERを仕掛ける CREATE TRIGGER trigger_users_deleted AFTER DELETE ON users FOR EACH ROW EXECUTE PROCEDURE process_deleted(); CREATE TRIGGER trigger_events_deleted AFTER DELETE ON events FOR EACH ROW EXECUTE PROCEDURE process_deleted(); CREATE TRIGGER trigger_entries_deleted AFTER DELETE ON entries FOR EACH ROW EXECUTE PROCEDURE process_deleted();
  • 64. -- テストデータを投入する INSERT INTO users (name, pass) VALUES ('ryu', 'xxx'); INSERT INTO users (name, pass) VALUES ('ken', 'xxx'); INSERT INTO events (user_id, name) VALUES (1, '〇〇勉強会'); INSERT INTO events (user_id, name) VALUES (1, '××勉強会'); INSERT INTO events (user_id, name) VALUES (2, '△△勉強会'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (1, 1, '参加', 'いち'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (1, 2, '参加', '参加します'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (2, 1, 'キャンセル', 'ごめんね'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (2, 2, '参加', 'にばん'); INSERT INTO entries (event_id, user_id, stat, message) VALUES (3, 2, '参加', 'よろしく');
  • 65. -- テストデータを確認する testdb=# SELECT * FROM users; user_id | name | pass ---------+------+------ 1 | ryu | xxx 2 | ken | xxx (2 rows) testdb=# SELECT * FROM events; event_id | user_id | name ----------+---------+------------ 1 | 1 | 〇〇勉強会 2 | 1 | ××勉強会 3 | 2 | △△勉強会 (3 rows) testdb=# SELECT * FROM entries;; entry_id | user_id | event_id | stat | message ----------+---------+----------+------------+------------ 1 | 1 | 1 | 参加 | いち 2 | 2 | 1 | 参加 | 参加します 3 | 1 | 2 | キャンセル | ごめんね 4 | 2 | 2 | 参加 | にばん 5 | 2 | 3 | 参加 | よろしく (5 rows)
  • 66. -- 削除されたデータの保存先は空 testdb=# SELECT * FROM deleted_users; user_id | name | pass ---------+------+------ (0 rows) testdb=# SELECT * FROM deleted_events; event_id | user_id | name ----------+---------+------ (0 rows) testdb=# SELECT * FROM deleted_entries; entry_id | user_id | event_id | stat | message ----------+---------+----------+------+--------- (0 rows)
  • 68. -- 他の関連するレコードも連鎖的に削除されている testdb2=# SELECT * FROM users; user_id | name | pass ---------+------+------ 2 | ken | xxx (1 row) testdb2=# SELECT * FROM events; event_id | user_id | name ----------+---------+---------- 3 | 2 | △△勉強会 (1 row) testdb2=# SELECT * FROM entries; entry_id | user_id | event_id | stat | message ----------+---------+----------+------+---------- 5 | 2 | 3 | 参加 | よろしく (1 row)
  • 69. -- 連鎖的に削除されたレコードは保存用のテーブルに退避されている testdb2=# SELECT * FROM deleted_users; user_id | name | pass ---------+------+------ 1 | ryu | xxx (1 row) testdb2=# SELECT * FROM deleted_events; event_id | user_id | name ----------+---------+------------ 1 | 1 | 〇〇勉強会 2 | 1 | ××勉強会 (2 rows) testdb2=# SELECT * FROM deleted_entries; entry_id | user_id | event_id | stat | message ----------+---------+----------+------------+------------ 1 | 1 | 1 | 参加 | いち 3 | 1 | 2 | キャンセル | ごめんね 2 | 2 | 1 | 参加 | 参加します 4 | 2 | 2 | 参加 | にばん (4 rows)
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83. CREATE TABLE emp ( empname text NOT NULL, salary integer ); CREATE TABLE emp_audit( operation char(1) NOT NULL, stamp timestamp NOT NULL, userid text NOT NULL, empname text NOT NULL, salary integer ); CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$ BEGIN -- -- Create a row in emp_audit to reflect the operation performed on emp, -- make use of the special variable TG_OP to work out the operation. -- IF (TG_OP = 'DELETE') THEN INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*; RETURN OLD; ELSIF (TG_OP = 'UPDATE') THEN INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*; RETURN NEW; ELSIF (TG_OP = 'INSERT') THEN INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*; RETURN NEW; END IF; RETURN NULL; -- result is ignored since this is an AFTER trigger END; $emp_audit$ LANGUAGE plpgsql; CREATE TRIGGER emp_audit AFTER INSERT OR UPDATE OR DELETE ON emp FOR EACH ROW EXECUTE PROCEDURE process_emp_audit();