How to get the executed SQL statement associated with QSqlTableModel::setData()?

3.2k views Asked by At

I am inserting/updating a database table from a Qt application using QSqlTableModelmethods setData, submitAll and commit. For logging purposes, I need to record the corresponding SQL statements. How can I do that? (I am looking at QSqlTableModel::query() but seems as if it only returns SELECTs)

Here is a simplified version of what I am doing.

QSqlTableModel *_dataTableModel = qobject_cast<QSqlTableModel*>(dataTableView->model());
_dataTableModel->setData(item, value);
_dataTableModel->database().transaction();
_dataTableModel->submitAll();
_dataTableModel->database().commit()
QSqlQuery _currentQuery = _dataTableModel->query();
qDebug() << _currentQuery.lastQuery();

The last line always prints a SELECT, even when I do an update or an insert.


update

Here is a self-sufficient code snippet. The setup is that, I have a UI with a QTableView and a QPushButton. clicked() signal of push button is captured in addNewRow() slot and a arbitrary value is inserted to the first cell. I am printing the result of the lastQuery() expecting it to be the insert statement but it is a SELECT statement for the given table. What am I doing wrong?

main.cpp

{
    QApplication a(argc, argv);
    test1 w;
    // connect to and open database
    w.setDataTable("MY_TEST_TABLE");
    w.show();
    return a.exec();
}

test1.h

public:
    void setDataTable(QString dataTableName);

private slots:
    void addNewRow();

test1.cpp

void test1::setDataTable( QString dataTableName )
{
    QSqlTableModel *tableModel = new QSqlTableModel(); 
    tableModel->setTable(dataTableName);
    tableModel->select();   
    ui.tableView->setModel(tableModel);
}

void test1::addNewRow()
{
    QSqlTableModel *tableModel = qobject_cast<QSqlTableModel*>(ui.tableView->model());
    if(!tableModel->insertRow(tableModel->rowCount())) {
            return;
    }       
    tableModel->setData(tableModel->index(0, 0), QVariant("123345")); 
    tableModel->database().transaction(); 
    if(!tableModel->submitAll()) {
            return;
    }  
    if (!tableModel->database().commit()) {                                          
            return;
    }     
    qDebug() << tableModel->query().lastQuery();
} 
1

There are 1 answers

22
László Papp On

Based on the official documentation:

Inserting, Updating, and Deleting Records

QSqlQuery can execute arbitrary SQL statements, not just SELECTs. The following example inserts a record into a table using INSERT: QSqlQuery query; query.exec("INSERT INTO employee (id, name, salary) " "VALUES (1001, 'Thad Beaumont', 65000)");

This works with any statements, and not just select. If you do it this way in a raw mode, you could always build a QString first, and use that for the QSqlQuery::exec() operation and then log it, or you could also use the following method to query the last statement if it is done dynamically for instance:

QString QSqlQuery::lastQuery() const

Returns the text of the current query being used, or an empty string if there is no current query text.

So, the only remaining bit is how to get the query object from your model class. This can be done with the following method:

QSqlQuery QSqlQueryModel::query() const

Returns the QSqlQuery associated with this model.