やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

QSqlTableModelでレコード絞込して更新&削除した

 絞り込めた!

成果物

github.com

対象環境

  • Raspbierry pi 3 Model B+
  • Raspbian stretch 2018-06-27
  • Qt 5.7.1

前回

コード抜粋

  1. DB接続
  2. テーブル作成
  3. モデル作成
  4. モデルからレコードを絞り込んで更新&削除
  5. 編集の確定
  6. select文でレコード確認

1. DB接続

QSqlDatabase db = QSqlDatabase::database("Memo");

2. テーブル作成

QSqlQuery query(db);
query.exec(tr("create table Memo(id INTEGER PRIMARY KEY AUTOINCREMENT, Memo TEXT, Created TEXT)"));
query.exec(tr("insert into Memo(Memo,Created) values('メモ内容だよ', '1999-12-31 23:59:59')"));

3. モデル作成

QSqlTableModel model(nullptr, db);
model.setTable("Memo");
model.setEditStrategy(QSqlTableModel::EditStrategy::OnManualSubmit); // これがないとmodel.removeRow, removeRowsが反映されない
model.select(); // これがないとquery.exec()で発行したinsert文のデータが残る

 Insertのときは不要だったが、Deleteするときは以下のメソッドが必要。

  • model.setEditStrategy(QSqlTableModel::EditStrategy::OnManualSubmit);
  • model.select();

4. モデルからレコードを絞り込んで更新&削除

  • model.setFilter(QString("Created <= '1999-12-31 23:59:59'"));のように条件を絞り込む
// 指定した条件のレコードを更新する
model.setFilter(QString("Created <= '1999-12-31 23:59:59'"));
qDebug() << model.rowCount();
for (int i = 0; i < model.rowCount(); i++) {
    QSqlRecord r = model.record(i);
    r.setValue("Memo", QVariant("filterで絞り込んでupdateRecordしたよ"));
    model.setRecord(i, r);
    if (!model.lastError().text().trimmed().isEmpty()) { qDebug() << model.lastError().text(); }
}
model.submitAll(); // なぜか以下コードの前に実行しないとsetRecordが反映されない!
// 指定した条件のレコードを削除する
model.setFilter(QString("Created = '1999-06-15 12:00:00'"));
qDebug() << model.rowCount();
model.removeRows(0, model.rowCount()); // filterに該当する全件削除
qDebug() << model.lastError().text();
  • 条件式がSQL文のwhere句と同様に文字列で入力するのが残念
    • model.setFilter(QSqlField, ...)みたいにできたら良かったのに
      • QSqlFiled f("列名"); f.setValue("値");とすればキーと値を指定できるからできそう
      • and, or, () の構文構造を表現するのが難しいから無理なのか?
  • insertRecord, setRecord, removeRecordの実行直後にmodel.submitAll();を実行しないと、以降の操作が反映されない
    • たぶんこれのせい: model.setEditStrategy(QSqlTableModel::EditStrategy::OnManualSubmit);

5. 編集の確定

if( model.submitAll() ) {
    model.database().commit();
    qDebug() << "commit()";
} else {
    model.database().rollback();
    qDebug() << "rollback()";
}

6. select文でレコード確認

query.exec(tr("select * from Memo"));
while (query.next()) {
    qDebug() << query.value(0) << "|" << query.value(1) << "|" << query.value(2);
}

所感

 QSqlTableModelにて、insert, update, delete, where(filter(絞込))はできた。order by(sort(並び替え))もできそう。あとはcreate tableができるかどうか。

SQL構文 QSqlTableModel対応メソッド
insert文 insertRecord(QSqlRecord)
update文 setRecord(QSqlRecord)
delete文 removeRow(int row), removeRows(int row, int count)
where句 setFilter(QString) ※列名 = '値'