SQL в Qt

Материал из Wiki семьи Белых
Перейти к навигации Перейти к поиску

Декларация SQL

В *.pro файле нужно подключить модуль sql. Для этого в секции QT делается запись

Code: Pro-файл
QT       += core gui sql

Что нужно проинклюдить:

Code: Sql Class
#include <QtSql>
#include <QSqlQuery>
#include <QSettings>
#include <QDebug>
  • QSetting нужен для настройки драйвера для работы конкретной базой из программных настроек.
  • QDebug пригодиться для вывода информации об ошибках

В классе создаются переменные:

Code: Sql Class
QSqlDatabase sql;
QSqlQuery q;

Выбор драйвера

MySQL

С MySQL в Qt можно работать через стандартный MySQL-драйвер или через ODBC-драйвер SQL-плагина.

MySQL драйвер чаще всего нужно пересобирать на конкретной платформе (если Qt установлена не из репозитория дистрибутива Linux). Вдобавок, он может конфликтовать с установленным MySQL ODBC Connector и не работать (например в Microsoft Windows XP).

После выбора драйвера работа с MySQL будет идентичной.

MySQL-драйвер

Code: Sql Class
sql = QSqlDatabase::addDatabase("QMYSQL");
sql.setDatabaseName(settings->value(SetKeyODBC.Schema).toString());
sql.setHostName(settings->value(SetKeyODBC.Host).toString());
sql.setPort(settings->value(SetKeyODBC.Port).toString().toInt());
sql.setUserName(settings->value(SetKeyODBC.User).toString());
sql.setPassword(settings->value(SetKeyODBC.Password).toString());
sql.setConnectOptions("SSL_KEY=/etc/my.cnf.d/ssl/client-key.pem;SSL_CERT=/etc/my.cnf.d/ssl/client-cert.pem;CLIENT_IGNORE_SPACE=1");

Последняя строка нужна, если клиент использует SSL-авторизацию.

MyODBC-драйвер

Code: Sql Class
sql = QSqlDatabase::addDatabase("QODBC3");
sql.setDatabaseName("Driver={MySQL ODBC 3.51 Driver};SERVER="+settings->value(SetKeyODBC.Host).toString()+";DATABASE="+ \
settings->value(SetKeyODBC.Schema).toString()+";UID="+settings->value(SetKeyODBC.User).toString()+";PWD="+ \
settings->value(SetKeyODBC.Password).toString()+";");

Автоматический выбор драйвера

На примере Microsoft Windows XP

Code: Sql Class
#if defined(Q_OS_WIN)
    if (QSysInfo::WindowsVersion==QSysInfo::WV_XP)
    {
        sql = QSqlDatabase::addDatabase("QODBC3");
        sql.setDatabaseName("Driver={MySQL ODBC 3.51 Driver};SERVER="+settings->value(SetKeyODBC.Host).toString()+";DATABASE="+ \
                             settings->value(SetKeyODBC.Schema).toString()+";UID="+settings->value(SetKeyODBC.User).toString()+ \
                             ";PWD="+settings->value(SetKeyODBC.Password).toString()+";");
    }
    else
    {
#endif
        sql = QSqlDatabase::addDatabase("QMYSQL");
        sql.setDatabaseName(settings->value(SetKeyODBC.Schema).toString());
        sql.setHostName(settings->value(SetKeyODBC.Host).toString());
        sql.setPort(settings->value(SetKeyODBC.Port).toString().toInt());
        sql.setUserName(settings->value(SetKeyODBC.User).toString());
        sql.setPassword(settings->value(SetKeyODBC.Password).toString());
#if defined(Q_OS_WIN)
    }
#endif

Запрос к СУБД

Переменная MyQuery типа QString содержит строку запроса к MySQL

Code: Sql Class
bool ok;
ok = sql.open();
if (ok)
{
    q.setForwardOnly(true); 
    ok=q.prepare(MyQuery);
    if (ok)
    {
        ok=q.exec();
        if (!ok)
            {qDebug () << q.lastError ();}
    }
    else
        {qDebug () << q.lastError ();}
    sql.close();
}
else
    {qDebug () <<sql.lastError ();}

Добавление или обновление записи

Записи добавляются или обновляются одинаковым методом.

Code: Sql Class
bool ok;
ok = sql.open();
if (ok)
{
    q.setForwardOnly(true); 
    q.prepare("INSERT INTO my_table (Filed1, Filed2, Filed3) VALUES (:valuefiled1, :valuefiled2, :valuefield3);");
    my_query.bindValue(":valuefield1", "value1");
    my_query.bindValue(":valuefield2", "value2);
    my_query.bindValue(":valuefield3", "value3");
    if (ok)
    {
        ok=q.exec();
        if (!ok)
            {qDebug () << q.lastError ();}
    }
    else
        {qDebug () << q.lastError ();}
    sql.close();
}
else
    {qDebug () <<sql.lastError ();}

Чтение результата запроса

Code: Sql Class
QVariant MyVariable1;
QVariant MyVariable2;
int indexField;
QString nameField;
indexField=X;
nameField="Name Field";
while (q.next())
{
    MyVariable1=q.value(indexField);
    MyVariable2=q.value(q.record().indexOf(nameField));
}
  • Замечание: при такой организации считывания в переменные Variable1 и Мфкшфиду2 попадут только данные из последней записи.
  • Привести запись к нужному типу данных можно соответствующей функцией класса QVariant.