TRIGGERの書き方について

このQ&Aのポイント
  • MySQLで株の履歴を作るためにTRIGGERを使用したいが、UPDATE文がエラーとなる
  • エラーメッセージは「#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near INTO a_lateststock SET d2_usr_id = NEW.a2_usr_id, d3_latest_volume = NEW.a4_latest_volume; ' at line 5」
  • INSERT INTO文は正常に動作するが、UPDATE文がうまく動作しない。TRIGGERはUPDATEも機能するはず
回答を見る
  • ベストアンサー

TRIGGERの書き方について

MYSQLで株の履歴を作っています。 テーブルとしては、株を購入するユーザー書き込み用のa_nowstock、書き込み履歴を記録するa_nowstock_history、最新の保有株を記録するa_lateststockとなります。 テーブル a_nowstock    (a1_id(自動取得),a2_user_id,a3_usr_volume,a4_latest_volume) a_nowstock_history(b1_id(自動取得),b2_user_id,b3_usr_volume) a_lateststock (d1_id(自動取得),d2_user_id,d3_latest_volume) a_nowstock はユーザーが書き込むテーブル a_nowstock_historyは書き込み履歴 a_lateststockは最新保有情報のみのデータとなります。 これをTRIGGERで処理するために下記のようにSQLで指示してみました。 DELIMITER // CREATE TRIGGER a_ref BEFORE INSERT ON a_nowstock FOR EACH ROW BEGIN INSERT INTO a_nowstock_history SET b2_usr_id = NEW.a2_usr_id, b3_usr_volume = NEW.a3_usr_volume; UPDATE INTO a_lateststock SET d2_usr_id = NEW.a2_usr_id, d3_latest_volume = NEW.a4_latest_volume; END; // DELIMITER ; しかしながら #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near INTO a_lateststock SET d2_usr_id = NEW.a2_usr_id, d3_latest_volume = NEW.a4_latest_volume; ' at line 5 というエラーが出てしまいます。 DELIMITER // CREATE TRIGGER a_ref BEFORE INSERT ON a_nowstock FOR EACH ROW BEGIN INSERT INTO a_nowstock_history SET b2_usr_id = NEW.a2_usr_id, b3_usr_volume = NEW.a3_usr_volume; END; // DELIMITER ; のように、INSERT INTO だけだと問題なく作動するため、UPDATEがうまくいっていないようです。 TRIGGERはUPDATEも機能するはずなのですが、うまくいきません。 アドバイスいただけましたら幸いです。 よろしくお願いいたします。

  • MySQL
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

INSERT INTO ... SET ... はMySQLの拡張構文ですが、UPDATE INTO という構文は目にしたことはありません。 DELIMITER // CREATE TRIGGER a_ref BEFORE INSERT ON a_nowstock FOR EACH ROW BEGIN INSERT INTO a_nowstock_history SET b2_usr_id = NEW.a2_usr_id, b3_usr_volume = NEW.a3_usr_volume; UPDATE a_lateststock SET d2_usr_id = NEW.a2_usr_id, d3_latest_volume = NEW.a4_latest_volume; END; // DELIMITER ; にするとどうなりますか。

tajix14
質問者

お礼

出来ました! 有難うございました!!

関連するQ&A

  • TRIGGERの書き方について 再質問

    以前質問したものです。解決したと思っていたのですが、エラーが無くなただけで解決はしてませんでしたので再度質問いたします。 MYSQLで株の履歴を作っています。 テーブルとしては、株を購入するユーザー書き込み用のa_nowstock、書き込み履歴を記録するa_nowstock_history、最新の保有株を記録するa_lateststockとなります。 テーブル a_nowstock    (a1_id(自動取得),a2_user_id,a3_usr_volume,a4_latest_volume) a_nowstock_history(b1_id(自動取得),b2_user_id,b3_usr_volume) a_lateststock (d1_id(自動取得),d2_user_id,d3_latest_volume) a_nowstock はユーザーが書き込むテーブル a_nowstock_historyは書き込み履歴 a_lateststockは最新保有情報のみのデータとなります。 これをTRIGGERで処理するために下記のようにSQLで指示してみました。 DELIMITER // CREATE TRIGGER a_ref BEFORE INSERT ON a_nowstock FOR EACH ROW BEGIN INSERT INTO a_nowstock_history SET b2_usr_id = NEW.a2_usr_id, b3_usr_volume = NEW.a3_usr_volume; UPDATE a_lateststock SET d2_usr_id = NEW.a2_usr_id, d3_latest_volume = NEW.a4_latest_volume; END; // DELIMITER ; これでトリガーを登録すると、エラーは出ないのですが、実際に a_nowstock に入力してみると、a_nowstock_historyには反映されるものの、a_lateststock には何も反映されません。 調べてみてもTRIGGERの中でUPDATEする方法が見当たらず途方に暮れています。 詳しい方、大変恐縮ですがアドバイス願います。

    • ベストアンサー
    • MySQL
  • TRIGGER上の足し算について

    MYSQLで株の履歴を作っています。 テーブルとしては、株を購入するユーザー書き込み用のa_nowstock、最新の保有株を記録するa_lateststockとなります。 テーブル a_nowstock    (a1_id(自動取得),a2_user_id,a3_buy_stock_volume) a_lateststock (d2_user_id(PRIMARY),d3_latest_volume) a_nowstock が入力されたら、最新数量を足し算してa_lateststockの中のd3_latest_volumeを更新します。 これをTRIGGERで処理するために下記のようにSQLで指示してみました。 DELIMITER // CREATE TRIGGER a_ref BEFORE INSERT ON a_nowstock FOR EACH ROW BEGIN INSERT INTO a_lateststock SET d2_usr_id = NEW.a2_usr_id, d3_latest_volume = NEW.a3_buy_stock_volume ON DUPLICATE KEY UPDATE d2_usr_id = NEW.a2_usr_id, d3_latest_volume = d3_latest_volume + NEW.a3_buy_stock_volume; END; // DELIMITER ; しかしながら、下記の通りエラーとなります。 #1054 - Unknown column 'd3_latest_volume ' in 'field list' d3_latest_volumeをold.d3_latest_volumeとして指示しても同様です。 #1054 - Unknown column 'old.d3_latest_volume ' in 'field list' WEB上のMySQL リファレンスマニュアルの記載(UPDATE persondata SET age=age+1;)を見る限り足し算は可能と考えています。 どこに問題があるか詳しい方ご教授頂けましたら幸いです。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • トリガーで計算させた値を履歴として記録するには

    株の購入履歴をトリガー内部で計算したいと考えています。 buying_stockの購入をすると、トリガーで最新の数量を計算しnow_stockテーブルに最新情報を記入、更新します。 テーブル ●buying_stock d1(プライマリ),d2_usr_id,d3_stock_id,d4_buy_stock_volume, ●now_stock f2_stock_id(プライマリ),f3_stock_name,f4_latest_stock_volume トリガ DELIMITER // CREATE TRIGGER a_ref0 BEFORE INSERT ON buying_stock FOR EACH ROW BEGIN INSERT INTO now_stock SET f2_stock_id=NEW.d3_stock_id,f3_stock_name=f3_stock_name,f4_latest_stock_volume=f4_latest_stock_volume+NEW.d4_buy_stock_volume ON DUPLICATE KEY UPDATE f2_stock_id=NEW.d3_stock_id,f3_stock_name=f3_stock_name,f4_latest_stock_volume=f4_latest_stock_volume+NEW.d4_buy_stock_volume; END; // DELIMITER ; ここまでは出来ました。 ただ、これでは最新価格は残りますが、購買履歴が残りません。 そこで、下記のトリガーを作成しました。 テーブル ●stock_history g1(プライマリ),g2_stock_id,g3_stock_name,g4_latest_stock_volume トリガー DELIMITER // CREATE TRIGGER a_ref000 BEFORE INSERT ON now_stock FOR EACH ROW BEGIN INSERT INTO stock_history SET g2_stock_id=NEW.f2_stock_id,g3_stock_name=NEW.f3_stock_name,g4_latest_stock_volume=NEW.f4_latest_stock_volume; END; // DELIMITER ; しかしながら、g3_stock_nameとg4_latest_stock_volumeがNULLになってしまいます。 古い購入履歴と最新の購入数は別物として捉えられているようです。 一方、同一のものとして指示するために、テーブルをg2_stock_id(プライマリ),g3_stock_name,g4_latest_stock_volumeとすると、Duplicate違反を指摘されます。 トリガーで計算した後の履歴を残すためにはどのような方法があるでしょうか? テーブルには ●stock_name a1(プライマリ),a2_stock_id,a3_stock_name, というものもございますので、これを使用すれば出来るのかもしれません。 ご指導いただきたくお願いいたします。

    • ベストアンサー
    • MySQL
  • 特定カラム値が規定値以上になった場合発動するトリガ

    MySQLのトリガについて教えてください。 投票システムを作っています。 テーブル名 abc ( abc1_id(プライマリ) , abc2_vote_volume(INT) ) テーブル名 def ( def1_id(プライマリ) , def2_vote_volume(INT) ) があります。 テーブル名 abc にある abc2_vote_volume(INT)にはユーザーが1票づつ投票します。 abc2_vote_volume(INT)が49までのうちは何も起こらず、 abc2_vote_volume(INT)が50を超えたら「テーブル名 def 」に全てをコピーしていくトリガの作成を考えました。 私が考えたのは下記の表現なのですが、エラーとなります。 FOR AS IF UPDATE 49<NEW.adc2_vote_volume が見るからに怪しいのですが、改定方法が分かりません。 詳しい方、ご教授頂けますようお願いいたします。 DELIMITER // CREATE TRIGGER a_ref AFTER UPDATE ON abc FOR AS IF UPDATE 49<NEW.adc2_vote_volume INSERT INTO def SET def1_id =NEW.abc1_id,abc2_vote_volume=NEW.abc2_vote_volume ON DUPLICATE KEY UPDATE def1_id =NEW.abc1_id,abc2_vote_volume=NEW.abc2_vote_volume; END; // DELIMITER

    • ベストアンサー
    • MySQL
  • 【SQL文】Insert into文で文法エラー

    insert into文で思ったような結果がでません。SQL文にお詳しい方、ご教授いただけますでしょうか? SQLは初心者レベルです。 期待している結果: テーブルT-BBSにT-USRのusr-id全リストを入れて、T-BBSのa,b,cには固定の数値を入れたいと思っています。 テーブル例: テーブル名:T-BBS ,カラム:usr-id,a,b,c, テーブル名:T-USR, カラム:usr-id 結果 user-id | a | b | c 2 |1 | 2 | 3 3 |1 | 2 | 3 4 |1 | 2 | 3 7 |1 | 2 | 3 私が考えたSQL文ですが、 INSERT INTO T-BBS(SELECT user-id FROM T-USR,1,2,3) →×(文法エラー) INSERT INTO T-BBS(user-id,a,b,c) VALUES (SELECT user-id FROM T-USR,1,2,3)→× 文法エラー INSERT INTO T-BBS(user-id,a,b,c) VALUES ((SELECT user-id FROM T-USR),1,2,3)→×サブクエリが複数行を含んでいる ちなみにデータベースはH2 Databaseというものみたいですが、mySQLと方言は同じという認識をもってます。 以上宜しくお願いします。

    • ベストアンサー
    • MySQL
  • WHERE句に複数のユーザーIDがある場合

    MySQLで購入管理データを作っています。 buying_table`(`b_usr_id`, `b_buy_volume`, `b_buyname`) `usr_table`(`u_usr_id`, `u_buy_volume`, `u_buyname`) の2つのテーブルがあります。 `usr_table` には100件のユーザーデータが入っています。 このうち特定のユーザーについてbuying_table`に複写します。 ユーザー名を1001に指定し下記のSQL文を行うと、無事複写が出来ました。 INSERT INTO `buying_table`(`b_usr_id`, `b_buy_volume`, `b_buyname`) SELECT `u_usr_id`, `u_buy_volume`, `u_buyname`, FROM `usr_table` WHERE `u_usr_id`=('1001') 今回は、()の中で、複数のユーザー名を指定し、インサートをする必要があります。 そこで、サブクエリの複数指定で使用するANYを使用し下記のSQL文にしたのですがエラーになります。 INSERT INTO `buying_table`(`b_usr_id`, `b_buy_volume`, `b_buyname`) SELECT `u_usr_id`, `u_buy_volume`, `u_buyname`, FROM `usr_table` WHERE `u_usr_id`=ANY('1001','1004','1005') #1064 - You have an error in your SQL syntax; check the manual サブクエリなら簡単なんですが、このように「単純に文字が入っている場合の複数設定」はどう記載すればいいか教えてください。 事情があり()の中でユーザー名が複数カンマ区切りされている以外の設定は出来ない状況です。 宜しくお願い致します。 CentOS6.3 MySQL5.5です

    • ベストアンサー
    • MySQL
  • トリガーについて

    このジャンルでお願いします。 次のようなテーブルで DROP TABLE IF EXISTS item; CREATE TABLE IF NOT EXISTS item ( id int(11) NOT NULL AUTO_INCREMENT, parent_id INT, name varchar(32) NOT NULL, level int NOT NULL, FOREIGN KEY (parent_id) REFERENCES item(id) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO item (parent_id, name) VALUES (null, 'item1'); INSERT INTO item (parent_id, name) VALUES (1, 'item2'); INSERT INTO item (parent_id, name) VALUES (2, 'item3'); INSERT INTO item (parent_id, name) VALUES (3, 'item4'); INSERT INTO item (parent_id, name) VALUES (2, 'item5'); INSERT INTO item (parent_id, name) VALUES (null, 'item6'); INSERT INTO item (parent_id, name) VALUES (6, 'item7'); INSERT INTO item (parent_id, name) VALUES (null, 'item8'); DROP PROCEDURE IF EXISTS UPDATE_LEVEL; DELIMITER // CREATE PROCEDURE UPDATE_LEVEL() BEGIN DECLARE CNT INT; DECLARE LVL INT; SET LVL=1; UPDATE item SET level=0; UPDATE item SET level=LVL WHERE parent_id IS NULL; SELECT COUNT(*) INTO CNT FROM item WHERE level=LVL; WHILE CNT>0 DO UPDATE item INNER JOIN (SELECT id FROM item WHERE level=LVL) as temp ON parent_id=temp.id SET item.level=LVL+1; SET LVL=LVL+1; SELECT COUNT(*) INTO CNT FROM item WHERE level=LVL; END WHILE; END // DELIMITER ; DROP TRIGGER IF EXISTS TRG_INSERT_ITEM; DELIMITER // CREATE TRIGGER TRG_INSERT_ITEM AFTER INSERT ON item FOR EACH ROW BEGIN CALL UPDATE_LEVEL(); END; // DELIMITER ; itemテーブルにinsertした場合にトリガーでUPDATE_LEVEL()を実行するようにしているのですが、 実際に挿入すると、 >Can't update table 'item' in stored function/trigger because it is already used by statment which invoked this stored function/trigger . このようなエラーが出てしまいます・・・ UPDATE_LEVEL()にinsertらしき記述はないと思うのですが、 これはなぜこのようなエラーが出るのでしょうか?

    • ベストアンサー
    • MySQL
  • phpmyadminはトリガーやIF文を使えますか

    mysql> delimiter $$ mysql> create trigger trigger_update after update on user for each row -> begin -> update address set name = new.name where name = old.name; -> end; -> $$ mysql> delimiter ; こちらをphpmyadminでどのようにしたら使うことができますか。

    • ベストアンサー
    • MySQL
  • トリガで複数行のインサートを実行したい

    mysql 5.5.16で、全体ユーザーから誕生日が来た人だけを選別する仕組みを作っています。 テーブル user (id_1 INT, user_1 TEXT,count_1 INT,nextbirthday_1 DATETIME) テーブル 20years (id_2 INT, user_2 TEXT,nextbirthday_2 DATETIME) userテーブルには1000人の19才ユーザーが配置されています。 このリストから「20才の誕生日が着たら20yearsテーブルに複写させる」ことを考えました。 まずは、EVENT でrecordにある1000人のユーザー全ての count_1 を毎日1回づつUPDATEさせます。 このアップデートをTRIGGERとして、誕生日と現在時間を見合わせ、誕生日が現在時間より古いユーザーは(誕生日が来たものは)20yearに複写させることを考えました。 その案が下記のEVENT とTRIGGERです。 ******************************** CREATE EVENT happybirthday ON SCHEDULE EVERY 1 DAY STARTS '2012-04-25 09:00:00' ENDS '2013-03-31 09:00:00' DO UPDATE record SET count_1 = count_1 + 1; ******************************** DELIMITER // CREATE TRIGGER 20_trigger AFTER UPDATE ON record FOR EACH ROW BEGIN IF(SELECT NEW.nextbitthday_1 <= NOW()) THEN INSERT INTO 20years SET id_2=NEW.id_1,user_2=NEW.user_1,nextbirthday_2=NEW.nextbirthday_1 ON DUPLICATE KEY UPDATE id_2=NEW.id_1; END IF; END; // DELIMITER ; ******************************** FOR EACH ROW BEGIN で全てのユーザーの誕生日を見に行き、誕生日に4人が該当すれば4人が20yearsに複写されるはずです。 しかし実際には、該当する一番上の一人だけしか複写させることが出来ませんでした。 (本日誕生日のユーザーが4人いて、4/16以前が誕生日の人が10人いた場合、それら合計14人のうち、userテーブル上で一番上に位置するユーザーだけが複写される) このトリガの書き方では、FOR EACH ROW BEGINと設定しているにも関わらず、全てのユーザーに対してトリガ作業を行わず、上から一人目を抽出した時点で作業を終了しているようです。 アドバイスを頂けましたら幸いです。 尚、ニーズは誕生日が来たユーザーだけを移動することですので、私の発案の方法に限らずもっといい方法があればアドバイスをお願いいたします。 追伸 IF節を全て外しても同様に一人しか抽出しませんでしたので、IF節が悪さをしている訳ではないようです。 よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • OracleのTrigger(トリガー)について

    いつもご親切にありがとうございます。 Oracleのトリガーについて教えてください。 テーブルA ----------------- 日付 date型 品名 char(15) 営業所 cahr(5) フラグ char(1) データをINSERTする際に、下記のように変更したいです。 (1)日付が2月且つ、営業所が00001の場合は99999に変更、 (2)日付が2月且つ、品名の後ろ5桁が00001の場合後ろ5桁だけを99999に変更 下記のようにトリガーを作成しているんですけど、 (2)をどのように入れたらよいでしょうか? CREATE OR REPLACE TRIGGER TRG_テーブルA BEFORE INSERT ON テーブルA REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW BEGIN IF ( to_char(:NEW.日付,'YYYYMM') = '201502' ) AND ( :NEW.営業所 = '00001' ) THEN :NEW.営業所 := '99999'; END IF; END; / よろしくお願いします。