いいえ。INSERTステートメントからストアドプロシージャを呼び出すことはできません。
INSERTステートメントからストアドプログラムを呼び出す方法はありますが、ユーザー定義関数である必要があります。次に例を示します。
INSERT INTO sometable (col)
SELECT IF( user_defined_function() , 'abc' , 'abc' )
ただし、その関数は、結果の行が重複キー例外をスローするかどうかに関係なく呼び出されます。ONDUPLICATEKEY句内でユーザー定義関数を参照することもできます。
INSERT INTO sometable (col1)
SELECT IF( user_defined_function() , 'abc' , 'abc' )
ON DUPLICATE KEY UPDATE col1 = IF( udf_duplicate() , VALUES(col1), VALUES(col1) )
これらのコンストラクトのバイナリロギング(行とステートメント)には問題があることに注意してください。これらの関数の機能によっては、このタイプのステートメントはレプリケーションに対して「安全」ではない場合があります。
ですから、あなたが本当にこのアプローチを使いたくないと思います。単一の行を挿入する場合は、INSERT ... ON DUPLICATE KEY UPDATE ...ステートメントを実行してから、影響を受ける行の数を確認する方がよいでしょう。影響を受ける行の値1は、行が挿入されたことを示します。影響を受ける行の値2は、行が更新されたことを意味するため、必要なプロシージャを条件付きで呼び出すことができます。
行が挿入または更新されるたびにこれらのストアード・プロシージャーのアクションが呼び出されるようにしたい場合は、AFTERINSERTおよびAFTERUPDATEトリガーを検討してください。(AFTERUPDATEトリガーがONDUPLICATE KEY UPDATEから起動されることを確認するためにテストする必要があります...古いバージョンのMySQLには、AFTER UPDATEトリガーが呼び出されないという問題がありました。)
編集:
元の質問に対する最新の更新では、このINSERTステートメントがMySQLストアドプロシージャ内から実行されることが指定されています。
このタイプのアプローチをお勧めします:
DECLARE affected_rows INT;
INSERT INTO sometable (id,foo) VALUES (123,'bar')
ON DUPLICATE KEY UPDATE foo = VALUES(foo);
SELECT ROW_COUNT() INTO affected_rows;
IF affected_rows = 1 THEN
CALL stored_procedure_after_insert();
ELSE
CALL stored_procedure_after_update();
END IF;
Q:では、「更新」後、影響を受ける行数は0になりますか?
A:行に変更が加えられていない場合(INSERT ... ON DUPLICATE KEY UPDATE
ステートメントによって、ROW_COUNT()関数は0を返します。
行が挿入されておらず、単一の行が更新されている場合、ROW_COUNT()関数は2を返します。
0と2を取得することの違いは、行が実際に変更されているかどうかです。更新の結果、行が行の現在の内容と同じになる場合(「変更は行われません」)、ROW_COUNT()は0を返します。更新の結果、行が変更される場合、ROW_COUNT() 2になります。