TRIGGER上でのMySQL株の足し算について

このQ&Aのポイント
  • MySQLのTRIGGERを使用して株の足し算を行いたいがエラーが発生している。
  • 株の数量を更新するためのTRIGGERを作成しようとしているが、Unknown columnのエラーが発生している。
  • 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
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

おそらくtypoですね 2点確認してください。 (1)「user」と「usr」を打ち間違えています (2)「d3_latest_volume」の後ろに全角スペースが入っています エラーメッセージを見る限り(2)がとくに怪しいですね。 また競合するidをupdateしても仕方がないので INSERT INTO a_lateststock SET d2_usr_id = NEW.a2_usr_id, d3_latest_volume = NEW.a3_buy_stock_volume ON DUPLICATE KEY UPDATE d3_latest_volume = d3_latest_volume + NEW.a3_buy_stock_volume; で十分では?

tajix14
質問者

お礼

有難うございます。 ご指摘いただきました方法で対応可能でした。 単なるスペースミスでした。 御礼申し上げます。 お二人ともベストアンサーとさせて頂きたいのですが、おひとりと いうことで、今回はミスをご指摘いただきましたyambejp様をベスト アンサーとさせていただきます。 本当にありがとうございました。

その他の回答 (1)

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

いったんユーザー変数で受ける。 drop trigger a_ref; DELIMITER // CREATE TRIGGER a_ref BEFORE INSERT ON a_nowstock FOR EACH ROW BEGIN set @user_id := NEW.a2_user_id; set @busy_stock_volume := NEW.a3_buy_stock_volume; INSERT INTO a_lateststock (d2_user_id, d3_latest_volume ) values ( @user_id, @busy_stock_volume ) on duplicate key update d3_latest_volume = d3_latest_volume + @busy_stock_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 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
  • 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
  • トリガーで計算させた値を履歴として記録するには

    株の購入履歴をトリガー内部で計算したいと考えています。 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
  • 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
  • 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
  • トリガで複数行のインサートを実行したい

    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
  • 集約関数のDUPLICATEKEY UPDATE

    テーブルmoney、テーブルmoney2にある金額の合計をテーブルmoney3に1日に1回、EVENTでインサートします。money、money2の金額は随時変わるため、最終結果をmoney3に毎日更新していきます。 CREATE table money(g_usr_id INT,g_money INT); CREATE table money2(n_usr_id INT,n_money INT); CREATE table money_all(o_usr_id INT PRIMARY KEY NOT NULL,g_money_all INT,n_money_all INT); 構文 DELIMITER // CREATE EVENT money ON SCHEDULE EVERY 1 DAY STARTS '2012-09-05 00:30:00' ENDS '2013-03-31 00:30:00' DO BEGIN INSERT INTO money_all(o_usr_id,g_money_all,n_money_all) SELECT o_usr_id,SUM(g_money),SUM(n_money) FROM (SELECT g_usr_id AS o_usr_id,g_money,0 AS n_money FROM money UNION ALL SELECT n_usr_id,0,n_money FROM money2) AS T GROUP BY o_usr_id; END; // DELIMITER ; これで初日目の分は無事インサート出来たのですが、翌日以降EVENTがアップデートしようとするとDUPLICATE KEYエラーが出て更新できていません。(当たり前ですが) そこで下記のようにON DUPLICATE KEY UPDATE を付けてみたのですが、エラーになってしまいました。 質問です。 集約関数のON DUPLICATE KEY UPDATE以降はどのように書けばいいか、下記の構文を修正いただけませんでしょうか DELIMITER // CREATE EVENT money ON SCHEDULE EVERY 1 DAY STARTS '2012-09-05 00:30:00' ENDS '2013-03-31 23:30:00' DO BEGIN INSERT INTO money_all(o_usr_id,g_money_all,n_money_all) SELECT o_usr_id,SUM(g_money),SUM(n_money) FROM (SELECT g_usr_id AS o_usr_id,g_money,0 AS n_money FROM money UNION ALL SELECT n_usr_id,0,n_money FROM money2) AS T GROUP BY o_usr_id ON DUPLICATE KEY UPDATE g_money_all=NEW.SUM(g_money),n_money_all=NEW.SUM(n_money) FROM (SELECT g_usr_id AS o_usr_id,g_money,0 AS n_money FROM money UNION ALL SELECT n_usr_id,0,n_money FROM money2) AS T GROUP BY o_usr_id; END; // DELIMITER ; よろしくお願いいたします。(MySQL 5.1です)

    • ベストアンサー
    • 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
  • テーブル結合の条件指定について

    以下のようなテーブルが3つある場合に2つのテーブルにあるポイントを合計して取得したいと思っています。 ただ、外部結合しているtable_cに条件を与えるとうまく取得できません。 table_cにcdがある場合は条件を指定し、 ない場合は条件を指定しないようにするにはどうすればいいのでしょうか。 【table_a】 id    name ------------------ a1    aaa a2    bbb a3    ccc 【table_b】 b_id     a_id   user_id    point --------------------------------- b1     a1    00001    5 b2     a1    00002    2 b3     a3    00007    10 b4     a2    00356    10 【table_c】 c_id    user_id    cd     bonus_point ------------------------------------------------ c1     00001    cd_1    1 c2     00007    cd_2    1 c3     00356    cd_1    1 SELECT table_b.user_id as user_id , (ifnull(table_b.age_count) + ifnull(table_c.bonus_point, 0)) as total_point FROM table_a INNER JOIN table_b ON (table_b.a_id=table_a.a_id)    LEFT JOIN table_c ON (table_c.user_id=table_b.user_id) WHERE table_c.cd = 'cd_1' ORDER BY total_point desc ■結果 user_id    total_point ----------------------------- 00356     11 00001      6 ■求めたい結果 user_id    total_point ----------------------------- 00356     11 00001      6 00002     2 よろしくお願いします。

    • ベストアンサー
    • MySQL