2017-09-13 6 views
0

私はMySQLはアップデートに挿入

create trigger avoid_duplicated_sharing 
before insert on sharingevents 
for each row 
begin 
    if (select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0) then 
     delete from sharingevents where shared_note_id = NEW.shared_note AND shared_to = NEW.shared_to 
    END IF; 
END 

しかしphpmyadminのは私に次のエラー与えのphpMyAdminを介してデータベースでこのクエリを実行しようとしています:

MySQL said: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END IF' at line 7

つの質問:

  • スクリプトに何が問題なのですか?
  • BEFORE INSERTトリガーの後に、INSERT操作を実行しますか?

    いっそ
    if (exists (select 1 from sharingevents where shared_note_id = new.shared_note_id AND shared_to = new.shared_to) > 0) then 
        insert into sharingevents (shared_note_id,shared_to,permission_level) 
         values (NEW.shared_note_id,NEW.shared_to,NEW.permission_level); 
    end if; 
    

    または、sharingevents(shared_note-id, shared_to)に一意のインデックスを追加してから使用してください:ケースでは、私がINSERT INTO SharingEvents (SELECT * FROM NEW);

+0

を、あなたは同じ、挿入にそれを回すいます。 – Barmar

+0

あなたはそうです、私はクエリを以下のように変更しました: 'shared_note = NEW.shared_note_id AND shared_to = NEW.shared_to); ' – Maximetinu

+0

' INSERT INTO ... ON DUPLICATE KEY UPDATE'またはINSERT IGNOREクエリ?あなたのユースケースに合っていませんか? – Mjh

答えて

0

使用existsを削除する必要がありますしません

insert into sharingevents (shared_note_id, shared_to, permission_level) 
     values (NEW.shared_note_id, NEW.shared_to, NEW.permission_level) 
     on duplicate key update shared_note_id = values(shared_note_id); 

これにより、ペアがすでにテーブルに存在するすべての更新は無視されます。いいえifが必要です。

+0

同じエラー:/ '#1064 - あなたはSQL構文に誤りがあります。あなたのMariaDBサーバのバージョンに対応するマニュアルをチェックして、正しい構文が近くで使用するようにしてください。 5行目のsharedevents(shared_note_id、shared_to、permission_level)に挿入してください。 – Maximetinu

+0

括弧はアンバランスであり、 0 'を実行して' exists() 'の結果をテストします。 – Barmar

+0

2番目の推奨は良いですが、おそらくタッチしたくないアプリケーションコードを変更する必要があるため、トリガーで自動化しています。 – Barmar

0

count(shared_note_id, shared_to)は無効な構文です。 count(DISTINCT ...)を使用すると、複数の列名をCOUNT()に入れることしかできません。あなたのケースでは、列名をすべて入れる必要はありません。条件に一致する行の数を数えるにはCOUNT(*)を使用してください。あなたがに変更を加えるためにトリガーを使用することはできませんので

は、あなたが本当にあなたの問題を解決することはできません構文エラーを修正、残念ながらCOUNT()

に列名を入れる必要がある場合の詳細についてはcount(*) and count(column_name), what's the diff?を参照してください。同じテーブル。

Can triggers access tables?
A trigger can access both old and new data in its own table. A trigger can also affect other tables, but it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.

あなたはこれを達成するために、INSERT ... ON DUPLICATE KEY UPDATE、または同等のものを使用して発信者を再コーディングする必要があります:FAQから。

+0

私はその変更を行ったし、はい、間違いだった!ありがとう。しかし、それでもそれは動作しません。これで、END IFにエラーが表示される – Maximetinu

0

私は次のコードでそれを解決:

delimiter $$ 

create trigger avoid_duplicated_sharing 
before insert on sharingevents 
for each row 
begin 
    if (select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0) then 
     delete from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to; 
    end if; 
END$$ 

問題は区切り文字でした。

でも、私のトリガは機能しません。アプリケーションインサートが主キーを複製した場合、MySQLは次のエラースロー:あなたはそれを更新への挿入を回していない

#1442 - Can't update table 'sharingevents' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

+0

トリガは、トリガしている同じテーブルを変更することはできません。 – Barmar