実現したいこと
取引テーブルと口座テーブルを作成し、取引テーブルに内容を追加した際にトリガーで口座テーブルにも自動で入出金額が追記されるような機能を実装したいのですが、トリガーがうまく動かなくて詰まってしまいました。
SQLite初心者なので基本的な部分が抜けているかもしれませんが、解決方法などわかるようでしたら教えてもらえるとありがたいです。
前提
- macos monterey 12.5.1
- sqlite3 3.37.0
発生している問題
ターミナルからSQLiteを起動し、SQLを実行しても口座テーブルに1つのレコードしか追加されませんでした。
本来であれば3つのレコードが追加されることを想定しています。
口座テーブル(Account_Log)の出力結果は以下となります。
sql
1sqlite> .read test.sql 2sqlite> .header on 3sqlite> .mode column 4sqlite> SELECT * FROM Account_Log ; 5ID_AL Type Time Account Amount TP_ID 6----- ---- ------------------- ---------- ------ ----- 71 uj 2023-04-23 07:18:16 account01 1597.5 3
該当のソースコード(test.sql)
sql
1CREATE TABLE Trading_Log ( 2 'ID_TL' INTEGER PRIMARY KEY, 3 'Type' TEXT, 4 'Time' TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, 5 'LS' TEXT NOT NULL, 6 'Lot' REAL NOT NULL, 7 'Price' REAL NOT NULL, 8 'TP_ID' INTEGER, -- Take Profit 9); 10 11CREATE TABLE Account_Log ( 12 'ID_AL' INTEGER PRIMARY KEY, 13 'Type' TEXT, 14 'Time' TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, 15 'Account' TEXT, 16 'Amount' INTEGER, 17 'TP_ID' INTEGER 18); 19 20CREATE VIEW Trading_Result AS 21 SELECT 22 out_rec.TP_ID, 23 in_rec.Type, 24 DATETIME(in_rec.Time, 'localtime') AS 'Time', 25 in_rec.LS AS 'IN_LS', 26 in_rec.Lot AS 'IN_Lot', 27 out_rec.Lot AS 'OUT_Lot', 28 in_rec.Price AS 'IN_Price', 29 out_rec.Price AS 'OUT_Price', 30 CASE 31 WHEN in_rec.LS = 'Long' THEN ROUND(out_rec.Price - in_rec.Price, 3) * out_rec.Lot * 10000 32 WHEN in_rec.LS = 'Sort' THEN ROUND(in_rec.Price - out_rec.Price, 3) * out_rec.Lot * 10000 33 END AS 'Profit', 34 FROM Trading_Log in_rec 35 INNER JOIN Trading_Log out_rec 36 ON in_rec.ID_TL = out_rec.TP_ID; 37 38CREATE TRIGGER trg_TLtoAL INSERT ON Trading_Log 39 WHEN NEW.TP_ID IS NOT NULL 40 BEGIN 41 INSERT INTO Account_Log(Account, Amount, TP_ID) 42 SELECT 43 'Account01', 44 Profit, 45 NEW.TP_ID 46 FROM Trading_Result vw_tr WHERE vw_tr.TP_ID = NEW.TP_ID; 47 END; 48 49INSERT INTO Trading_Log('Type', LS, Lot, Price, TP_ID) VALUES('uj', 'Long', 1.5, 133.981, NULL); 50INSERT INTO Trading_Log('Type', LS, Lot, Price, TP_ID) VALUES('uj', 'Short', 1.5, 134.519, 1); 51INSERT INTO Trading_Log('Type', LS, Lot, Price, TP_ID) VALUES('uj', 'Long', 1.5, 134.718, NULL); 52INSERT INTO Trading_Log('Type', LS, Lot, Price, TP_ID) VALUES('uj', 'Short', 0.75, 134.931, 3); 53INSERT INTO Trading_Log('Type', LS, Lot, Price, TP_ID) VALUES('uj', 'Short', 0.75, 135.277, 3);
試したこと
あれこれ試してみましたが解決できず、アドバイスなどでもあれば教えてもらえると幸いです。
よろしくお願いいたします。
追記です。
記事内の処理をした後に、再度2番目のINSERTを実行するとトリガーは発動して口座サーバーに追記されます。
```sql
sqlite> INSERT INTO Trading_Log('Type', LS, Lot, Price, TP_ID) VALUES('uj', 'Short', 1.5, 134.519, 1);
sqlite> SELECT * FROM Account_Log ;
ID_AL Type Time Account Amount TP_ID
----- ---- ------------------- ---------- ------ -----
1 uj 2023-04-23 07:18:16 fx_oanda01 1597.5 3
2 uj 2023-04-23 09:17:55 fx_oanda01 8070.0 1
sqlite>
```
ただ、取引テーブルのレコードが重複してしまうので最初の一回で入力させたいです。
```sql
sqlite> SELECT * FROM Trading_Log ;
ID_TL Type Time LS Lot Price TP_ID
----- ---- ------------------- ----- ---- ------- -----
1 uj 2023-04-23 07:18:16 Long 1.5 133.981
2 uj 2023-04-23 07:18:16 Short 1.5 134.519 1
3 uj 2023-04-23 07:18:16 Long 1.5 134.718
4 uj 2023-04-23 07:18:16 Short 0.75 134.931 3
5 uj 2023-04-23 07:18:16 Short 0.75 135.277 3
6 uj 2023-04-23 09:17:55 Short 1.5 134.519 1
```
参考までに、viewの出力結果も記載しておきます。
```sql
sqlite> SELECT * FROM Trading_Result ;
TP_ID Type Time IN_LS IN_Lot OUT_Lot IN_Price OUT_Price Pips Profit
----- ---- ------------------- ----- ------ ------- -------- --------- ----- ------
1 uj 2023-04-23 16:18:16 Long 1.5 1.5 133.981 134.519 0.538 8070.0
3 uj 2023-04-23 16:18:16 Long 1.5 0.75 134.718 134.931 0.213 1597.5
3 uj 2023-04-23 16:18:16 Long 1.5 0.75 134.718 135.277 0.559 4192.5
1 uj 2023-04-23 16:18:16 Long 1.5 1.5 133.981 134.519 0.538 8070.0
sqlite>
```
よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー