質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

410閲覧

SQLiteのCREATE TRIGGERについて、INSERTしても一部しか反映されません。

ishiha

総合スコア6

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2023/04/23 07:40

編集2023/04/23 19:17

実現したいこと

取引テーブルと口座テーブルを作成し、取引テーブルに内容を追加した際にトリガーで口座テーブルにも自動で入出金額が追記されるような機能を実装したいのですが、トリガーがうまく動かなくて詰まってしまいました。

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);

試したこと

あれこれ試してみましたが解決できず、アドバイスなどでもあれば教えてもらえると幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ishiha

2023/04/23 09:27

追記です。 記事内の処理をした後に、再度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> ``` よろしくお願いします。
guest

回答1

0

ベストアンサー

Triggerの起動タイミングをデフォルトのBEFOREからAFTERに修正されるとよいかと思います。

SQL

1CREATE TRIGGER trg_TLtoAL AFTER INSERT ON Trading_Log

(正確な要件を理解できていないかもしれないのですが、その点はご了承ください)

投稿2023/04/23 10:08

neko_the_shadow

総合スコア2225

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ishiha

2023/04/23 10:17

コードを修正したところ意図した結果を得ることができました。 回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問