Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Запрос вставки
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Разработка баз данных
AD
Есть запросы вставки записи в таблицу, подобные данной:
QSqlQuery query(QSqlDatabase::database("conn_1"));
query.prepare(QString("insert into ScriptLayer(ScriptItemId, LayerNameId) values(%1, -1)").arg(id));
bool ins = query.exec();
Проверяю. ins = true. При этом в саму таблицу ничего не добавилось. Как такое возможно? Естественно, что при закрытии приложения никаких удалений не делаю.
BRE
А если в программе sqlbrowser попробовать добавить запись в эту базу?

Как создается таблица ScriptLayer?
AD
Цитата(BRE @ 28.3.2011, 13:11) *
А если в программе sqlbrowser попробовать добавить запись в эту базу?

Не пробовал. Попробую.

P.S. Да, создается.
Цитата(BRE @ 28.3.2011, 13:11) *
Как создается таблица ScriptLayer?

Она по-умолчанию создана.
MJIbIu
Цитата(AD @ 28.3.2011, 11:12) *
query.prepare(QString("insert into ScriptLayer(ScriptItemId, LayerNameId) values(%1, -1)").arg(id));

А попробуй как вот так
query.prepare(QString("insert into nameDB.ScriptLayer(ScriptItemId, LayerNameId) values(%1, -1)").arg(id));
AD
Цитата(MJIbIu @ 28.3.2011, 16:18) *
А попробуй как вот так
query.prepare(QString("insert into nameDB.ScriptLayer(ScriptItemId, LayerNameId) values(%1, -1)").arg(id));

Что за nameDB? У меня ведь запрос-то выполняется... По какой-то причине при выходе из БД удаляется запись. Непонятно почему.
MJIbIu
Цитата(AD @ 28.3.2011, 15:40) *
Цитата(MJIbIu @ 28.3.2011, 16:18) *
А попробуй как вот так
query.prepare(QString("insert into nameDB.ScriptLayer(ScriptItemId, LayerNameId) values(%1, -1)").arg(id));

Что за nameDB? У меня ведь запрос-то выполняется... По какой-то причине при выходе из БД удаляется запись. Непонятно почему.

query.prepare("INSERT INTO ИмяБД.ИмяТаблице VALUES (:value1,:value2);");
query.bindValue(":valut1", "значение 1");
query.bindValue(":value", "значение 2");
я делаю так
Если бы у тебя запрос бы выполнялся тогда бы и в БД заносились бы данные.

Цитата(AD @ 28.3.2011, 15:40) *
По какой-то причине при выходе из БД удаляется запись.

:huh:
Ты с какой СУБД работаешь ?
AD
Цитата(MJIbIu @ 28.3.2011, 16:52) *
query.prepare("INSERT INTO ИмяБД.ИмяТаблице VALUES (:value1,:value2);");
query.bindValue(":valut1", "значение 1");
query.bindValue(":value", "значение 2");
я делаю так
Если бы у тебя запрос бы выполнялся тогда бы и в БД заносились бы данные.

При добавлении я вижу, что в таблице появилась новая запись, значит, все же, добавилась. На счет ИмяДБ хотел уточнить. Я правильно понимаю, что имеется в виду имя соединения или же имеется в виду имя следующее - QSqlDatabase::database("connectionName").databaseName();

Цитата(MJIbIu @ 28.3.2011, 16:52) *
:huh:
Ты с какой СУБД работаешь ?

SQLiteAdmin в качестве СУБД. http://sqliteadmin.orbmu2k.de/
MJIbIu
Цитата(AD @ 28.3.2011, 17:36) *
При добавлении я вижу, что в таблице появилась новая запись, значит, все же, добавилась. На счет ИмяДБ хотел уточнить. Я правильно понимаю, что имеется в виду имя соединения или же имеется в виду имя следующее - QSqlDatabase::database("connectionName").databaseName();

Цитата(MJIbIu @ 28.3.2011, 16:52) *
:huh:
Ты с какой СУБД работаешь ?

SQLiteAdmin в качестве СУБД. http://sqliteadmin.orbmu2k.de/

create database ИмяБД character set utf8; вот что я имел виду
если у тебя создается тогда это не важно
Важнее то что у тебя после выхода твоей проги не сохраняются данные.
Выложи полный код. И покопайся в СУБД мб она как то настроено хитро всяко бывает

http://www.mysql.ru/docs/gruber/mg23.html
КОГДА СДЕЛАННЫЕ ИЗМЕНЕНИЯ СТАНОВЯТСЯ ПОСТОЯННЫМИ
Смахивает на твою проблему
AD
Цитата(MJIbIu @ 28.3.2011, 18:03) *
http://www.mysql.ru/docs/gruber/mg23.html
КОГДА СДЕЛАННЫЕ ИЗМЕНЕНИЯ СТАНОВЯТСЯ ПОСТОЯННЫМИ
Смахивает на твою проблему

Да. Похоже на данную проблему. Как это в СУБД решить, пока не нашел.
/// Вcmaвka строк в таблицу AztPage
bool SqlFileModel::insertRowsAztPage(int row, int count)
{
    if(tableName() != QString("AztPage")) return false;

    QStringList chart_names(valueElement("Azt/ChartFiles", QStringList()).toStringList());
    QString chart_name(chart_names.at(row));
    int sz = rowCount(), id = sz,
        stump_group_of_pages_id = 1;            ///< TODO: номер группы страниц (затычка)
    if(id < 0) id = 0;
    ++id;
    for(int i=0; i<sz; ++i)
    {
        QString file_name(record(i).value("SpatialFilePath").toString());
        if(chart_names.at(row).toLower() == file_name.toLower())
            return false;
    }
    QSqlDatabase db(QSqlDatabase::database("conn_1"));
    QString query_string(QString("insert into AztPage(Id, SpatialFilePath, GroupOfPagesId) values(%1, '%2', %3)")
                .arg(id).arg(chart_names.at(row)).arg(stump_group_of_pages_id));
    QSqlQuery query(db), q(db);
    query.prepare(query_string);
    q.prepare(QString("COMMIT;"));
    bool res = query.exec(), res_commit = q.exec();
    QString err(q.lastError().text());
    if(!res) return false;

    return true;
}

res = true, res_commit = false;
И в БД не попадает при выходе из приложения.
В err данном случае попадает следующая фраза
Цитата
cannot commit transaction - SQL statements in progress Unable to fetch row

Данный код тоже выдает сообщение предупреждение
QSQLiteDriver* p_driver((QSQLiteDriver*)QSqlDatabase::database("conn_1").driver());
bool is = p_driver -> commitTransaction();
if(!is)
        emit display(p_driver -> lastError().text(), true, false);

Цитата
cannot commit transaction - SQL statements in progress Unable to commit transaction.
Есть варианты как сделать? Копаюсь в ассистенте. Пока ничего не нашел.
AD
Буду рад, если поможете. Не понимаю, как сделать правильный commit транзакции. Возвращает ошибку, указанную в предыдущем посте. Повторюсь, что это необходимо, чтобы БД приняла данные, т.е. чтобы данные сохранились в БД. На данный момент получается такая фигня, что я вижу добавленные данные во время работы приложения. Но как только я перезапускаю приложение, данных нет. Сделать так, чтобы commit в итоге стал true не получается....
AD
Неужели ни у кого не было подобной проблемы при работе с SQLite?
MJIbIu
Цитата(AD @ 29.3.2011, 16:17) *
Буду рад, если поможете. Не понимаю, как сделать правильный commit транзакции. Возвращает ошибку, указанную в предыдущем посте. Повторюсь, что это необходимо, чтобы БД приняла данные, т.е. чтобы данные сохранились в БД. На данный момент получается такая фигня, что я вижу добавленные данные во время работы приложения. Но как только я перезапускаю приложение, данных нет. Сделать так, чтобы commit в итоге стал true не получается....

bool QSqlDatabase::commit ()
Выполняет транзакцию в базу данных, если она поддерживается драйвером и уже была начата транзакция посредством transaction(). Возвращает true в случае успеха операции. В противном случае возвращает false.
Замечание: Для некоторых баз данных фиксация транзакции завершится неудачно и возвратит false, если использовалась active query базы данных для SELECT. Сделайте запрос inactive перед выполнением фиксации транзакции.

http://www.javatalks.ru/ntopic9646.php
конечно там на java ну смысл я думаю тот же
AD
Цитата(MJIbIu @ 30.3.2011, 14:07) *
bool QSqlDatabase::commit ()
Выполняет транзакцию в базу данных, если она поддерживается драйвером и уже была начата транзакция посредством transaction(). Возвращает true в случае успеха операции. В противном случае возвращает false.
Замечание: Для некоторых баз данных фиксация транзакции завершится неудачно и возвратит false, если использовалась active query базы данных для SELECT. Сделайте запрос inactive перед выполнением фиксации транзакции.

http://www.javatalks.ru/ntopic9646.php
конечно там на java ну смысл я думаю тот же

Я умею читать ассистент. setAutocommit - в Qt нет. Сделал для запроса clear(), не прокатило. Что еще возможно? Данную ссылку уже сам находил - не помогло. Запрос делаю неактивным, но в БД запись не попадает.
AD
Вернулся к СУБД Paradox. Решение на данную проблему найти не смог. Буду пробовать ускорять работу запросов в Paradox
AD
В связи с тем, что скорость работы на Paradox маленькая, перешел обратно на SQLite. Проблема осталась. Не удается внести и запомнить записи. При транзакции коммит не удается сделать.
Выдает следующее сообщение
Цитата
cannot commit transaction - SQL statements in progress Unable to commit transaction

Самое странное, что записи из файла он в таблицу вставил нормально. Кто может помочь с этой проблемой. Уже несколько дней мучаюсь, решить не получается. Буду благодарен за помощь.

Вот функция, в которой транзакция не выполняется.
Раскрывающийся текст

/// Вcmaвka строк в таблицу AztPage
bool SqlFileModel::insertRowsAztPage(int row, int count)
{
    if(tableName() != QString("AztPage")) return false;

    QSqlDatabase db(QSqlDatabase::database("conn_1"));
    bool trans = db.transaction();

    QSqlQuery check_query(db);
    check_query.prepare("select max(Id) from AztPage");
    bool is_sel = check_query.exec(), is_next = check_query.next();
    QStringList chart_names(valueElement("Azt/ChartFiles", QStringList()).toStringList());
    QString chart_name(chart_names.at(row));
    int sz = rowCount(), id = sz, stump_group_of_pages_id = 1;    ///< TODO: номер группы страниц (затычка)
    ++id;
    if(is_sel && is_next)
        id = check_query.value(0).toInt(),
        ++id;
    for(int i=0; i<sz; ++i)
    {
        QString file_name(record(i).value("SpatialFilePath").toString());
        if(chart_names.at(row).toLower() == file_name.toLower())
            return false;
    }
    string fname(chart_name.replace(QString(QString(".") + QFileInfo(chart_name).suffix()),
                        QString(""), Qt::CaseInsensitive).toStdString());
    char* string_name_chart(const_cast<char*> (fname.c_str()));
    QString query_string(QString("insert into AztPage(Id, SpatialFilePath, GroupOfPagesId) "
                        "values(%1, '%2', %3)").arg(id).
                        arg(chart_names.at(row)).arg(stump_group_of_pages_id));
    QSqlQuery query(QSqlDatabase::database("conn_1"));
    query.prepare(query_string);
    bool res = query.exec();

    bool comm = db.commit();
    if(!comm)
    {
        QString error_string(db.lastError().text());
        int error_number = db.lastError().type();
    }

    return res;
}

MoPDoBoPoT
Цитата(QtAssistant)
bool QSqlQuery::isActive () const
...
Note: Of particular interest is an active query that is a SELECT statement. For some databases that support transactions, an active query that is a SELECT statement can cause a commit() or a rollback() to fail, so before committing or rolling back, you should make your active SELECT statement query inactive using one of the ways listed above.

Попробуй перед фиксацией транзакции для всех активных запросах вызвать clear()
AD
Цитата(MoPDoBoPoT @ 11.4.2011, 22:41) *
Попробуй перед фиксацией транзакции для всех активных запросах вызвать clear()

Пробовал. Не помогает.
AD
В результате долгих копаний. Кое-что смог выяснить. Исходя из этой статьи, выяснил, что БД SQLite может хранится в памяти, а может в файле. Вопрос. Как организовать правильное хранение в памяти? Т.е. что конкретно надо поменять в данном коде:
/// Функция для создания соединения с базой данных
bool createConnection(const QString& odbc_path)
{
    QSqlDatabase db(QSqlDatabase::database("conn_1"));
    if(db.isOpen()) db.close();

    db = QSqlDatabase::addDatabase("QSQLITE", "conn_1");
    db.setDatabaseName(odbc_path);

    if(!db.open())
    {
        QSqlError error(db.lastError());
        QMessageBox msg(QMessageBox::Critical, "Connections", error.text(), QMessageBox::Ok, 0);
        msg.exec();
        return false;
    }
    return true;
}

Куда это ":in_memory:" добавить? Ну и попутный вопрос к ViGOur: помнится где-то была статья и сборке плагина без сборки всего Qt. Дайте, пожалуйста, ссылку на эту статью. Заранее спасибо.
MoPDoBoPoT
Цитата(AD @ 12.4.2011, 10:32) *
Пробовал. Не помогает.

Возможно, что где-то ещё активные запросы, например, табличные модели.
Цитата(AD @ 12.4.2011, 15:18) *
Как организовать правильное хранение в памяти?

    db = QSqlDatabase::addDatabase("QSQLITE", "conn_1");
    db.setDatabaseName(":memory:");
AD
Цитата(MoPDoBoPoT @ 12.4.2011, 22:19) *
Возможно, что где-то ещё активные запросы, например, табличные модели.

А как в табличных моделях сделать неактивными запросы?
AD
Либо я чего-то не понял, либо еще что-то, но загружать БД в память, а потом сохранять в файл не получилось. Прошу, кто может помочь, помогите, пожалуйста. Очень необходимо поправить глюк с транзакциями. Я не понимаю в чем ошибка...
MoPDoBoPoT
Цитата(AD @ 14.4.2011, 11:38) *
Либо я чего-то не понял, либо еще что-то, но загружать БД в память, а потом сохранять в файл не получилось.

Если только приаттачить (ATTACH DATABASE) файл БД, после чего переписать туда данные. Но лучше разобраться с проблемой транзакций и писать сразу в файл. Мне кажется, можно попробовать создать отдельное соединение для изменения данных в БД, чтобы не искать активные запросы и сбрасывать их.
AD
Цитата(MoPDoBoPoT @ 14.4.2011, 22:49) *
Если только приаттачить (ATTACH DATABASE) файл БД, после чего переписать туда данные. Но лучше разобраться с проблемой транзакций и писать сразу в файл. Мне кажется, можно попробовать создать отдельное соединение для изменения данных в БД, чтобы не искать активные запросы и сбрасывать их.

Сделал новое соединение, специально, чтобы делать выборки и вставки в БД. В итоге получил следующую ошибку при транзакции:
Цитата
database is locked Unable to commit transaction

Как решить эту проблему?
MoPDoBoPoT
Странно. Блокировку можно получить, когда в рамках разных транзакций происходит попытка изменения БД, но у тебя же одно подключение читает, а другое пишет... Может ещё быть из-за уровня изоляции транзакции EXCLUSIVE, но я не думаю, что ты его указывал.
AD
Цитата(MoPDoBoPoT @ 19.4.2011, 22:29) *
Странно. Блокировку можно получить, когда в рамках разных транзакций происходит попытка изменения БД, но у тебя же одно подключение читает, а другое пишет... Может ещё быть из-за уровня изоляции транзакции EXCLUSIVE, но я не думаю, что ты его указывал.

Тоже считаю, что странно. Но пока ничего не выходит. А проблему очень надо решить. Буду безумно благодарен, если сможешь помочь. Никаких EXCLUSIVE не использовал.
AD
О. Все-таки каких-то результатов удалось добиться. Смысл в том, что модель, унаследованная от QSqlTableModel блокирует базу данных, в результате чего возникают данные ошибки. Попробую разобраться в этом, тем более, что я видел, что QSqlLite как-то странно работает с моделями. Об этом я видел в ассистенте сообщение.
AD
Проблема решена. Дело вот в чем. Моя модель SqlFileModel наследовалась от QSqlTableModel, а у QSqlTableModel есть особенность при работе с SQLite она блокирует БД, пока не выполняться все ее select-запросы, что мне изрядно мешало.

Решение состоит в том, что модель стал наследовать от QAbstractTableModel. Тогда все вставки в таблицу происходят без проблем.
MoPDoBoPoT
Цитата(AD @ 22.4.2011, 14:59) *
она блокирует БД, пока не выполняться все ее select-запросы

В смысле не вычитает все записи по запросу? Типо этого?
 while (myModel->canFetchMore())
     myModel->fetchMore();
AD
Цитата(MoPDoBoPoT @ 22.4.2011, 22:09) *
В смысле не вычитает все записи по запросу? Типо этого?

Да.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2022 IPS, Inc.