0

MySql の TRIGGER に問題があります。

notifications_posts
notification_id from_user   on_post_id  in_group_id date
2   1   162 3   2012-07-11 12:01:08
3   19  163 1   2012-07-11 12:03:26
4   19  164 1   2012-08-10 17:42:36
5   1   165 3   2012-08-29 12:14:01
6   1   165 3   2012-08-29 12:14:29
11  1   2   3   2012-08-29 14:38:42

たとえば、次のコマンドを使用して、投稿を削除する必要がある場合があります。

DELETE FROM posts WHERE posts.post_id = 165;

notification_idこの後、そのIDに従ってすべてのレコードを削除するTRIGGERが必要です。

これは私がこれまでに持っているものです:

DELIMITER $$
CREATE OR REPLACE TRIGGER CleanNotificationPosts
AFTER DELETE ON posts
FOR EACH ROW
BEGIN
    DELETE FROM notifications_posts WHERE notifications_posts.id = THAT_ID_TO_DELETE;
END $$
DELIMITER ;

私の構文は正しいですか?本当に区切り文字が必要ですか?

4

1 に答える 1

2
  1. 本当に区切り文字が必要ですか?

    現在使用している構文では: はい、デフォルト以外の区切り文字を使用する必要があります。そうしないと;CREATE TRIGGERステートメントがキーワードの;前で終了しEND、解析エラーが発生します (BEGIN ... ENDブロックが削除されないため)。終了しました)。

    ただし、そのブロック内にはステートメントが 1 つしかないため、実際に使用する必要はまったくありませんBEGIN ... END

    CREATE OR REPLACE TRIGGER CleanNotificationPosts
    AFTER DELETE ON posts
    FOR EACH ROW
    DELETE FROM notifications_posts WHERE notifications_posts.id = THAT_ID_TO_DELETE;
    

    この場合、ステートメントのデリミタを変更する必要はありません。;実際にCREATE TRIGGERステートメントが終了する場所です。

  2. 私の構文は正しいですか?

    ほとんどですが、完全ではありません。の代わりにTHAT_ID_TO_DELETE、 を使用する必要がありますOLD.post_idCREATE TRIGGER構文で述べたように:

    OLDエイリアスとを使用して、サブジェクト テーブル (トリガーに関連付けられたテーブル) の列を参照できますNEWOLD.col_name更新または削除される前の既存の行の列を参照します。NEW.col_name挿入する新しい行または更新後の既存の行の列を指します。

    また、OR REPLACEMySQL では無効です。代わりに、ステートメントをDROP TRIGGER IF EXISTS実行する前にできます。CREATE TRIGGER

    したがって:

    DROP TRIGGER IF EXISTS CleanNotificationPosts;
    CREATE TRIGGER CleanNotificationPosts
    AFTER DELETE ON posts
    FOR EACH ROW
    DELETE FROM notifications_posts WHERE notifications_posts.id = OLD.post_id;
    
  3. ただし、この状況では、実際にはトリガーをまったく使用する必要はありません (外部キー制約ON DELETE CASCADE十分であるため)。

    ALTER TABLE notifications_posts
      ADD FOREIGN KEY (id) REFERENCES posts (post_id) ON DELETE CASCADE;
    

    このような外部キー制約を追加するには、次の前提条件に注意してください。

    • 両方のテーブルが InnoDB ストレージ エンジンを使用する必要があります。

    • postsテーブルにpost_idは、最初の列であるインデックスが必要です。と

    • posts.post_idすべての非NULL notifications_posts.id(サイズと符号を含む列の型に至るまで) に一致するレコードが存在する必要があります。

于 2012-08-29T15:04:47.453 に答える