Russian Qt Forum

Qt => Базы данных => Тема начата: ecspertiza от Август 09, 2009, 12:34



Название: QSqlQueryModel как правильно обновить
Отправлено: ecspertiza от Август 09, 2009, 12:34
Вопрос довольно нубский как правильно обновить QSqlQueryModel ?

Но нужно обновить так что бы если юзверь редактировал 279 запись то после обновления таблица осталась на этой записи, делаю вот так
Код:
    int h = mainTable->verticalScrollBar()->sliderPosition();
    QModelIndex row = mainTable->currentIndex();

    model.setQuery("Запрос");
    if (row.row() != -1)
        mainTable->setCurrentIndex(row);

    mainTable->verticalScrollBar()->setSliderPosition(h);

всё нормально работает но если обновление идёт до 260 записи потом всё плохо и код перестаёт работать.

Как лудше это реализовать?


Название: Re: QSqlQueryModel как правильно обновить
Отправлено: Пантер от Август 09, 2009, 14:00
Используй fetchMore.


Название: Re: QSqlQueryModel как правильно обновить
Отправлено: break от Август 09, 2009, 15:09
Вообще то это не совсем правильно - у вас если я правильно понял получается что обновлениеконкретной строки осуществляется отдельным запросом, после чего надо заново сделать select из таблицы чтобы обновились данные в QSqlQueryModle и соответственно в ьабличке?

Если так то это неправильно и вызовет большие проблемы при работе с большим количеством строк - например если их около 1000 а я будуредактировать 999 - то после обновления строки буду ждать fetchAll каждый раз. Правильнее чтобы изменения сохранялись в модели а уже потом при нажатии пользователем "подтвердить" или просто по закрытию окна - отправлялись в БД.

Возможно я не врено понял ващу задачу, просто кусок исходника маловат, а вообще fetchAll (fetchMore) следует всегда избегать - не просто так все записи таблиц и запросов никогда не считываются сразу...


Название: Re: QSqlQueryModel как правильно обновить
Отправлено: ecspertiza от Август 09, 2009, 18:45
Задача в следующем, есть форма добавления\редактирования есть таблица у неё есть контекстное меню, и вот например пользователь на одной из записи кликнул редактировать, открылась форма он что то изменил, потом кликнул Ок затем выполнилась хранимка в БД, а потом обновление таблицы, но нужно что бы указатель остался на том же месте сделал так
Код:
    int h = mainTable->verticalScrollBar()->sliderPosition();
    QModelIndex row = mainTable->currentIndex();

    model.setQuery("Запрос");
    mainTable->verticalScrollBar()->setSliderPosition(h);

    if (row.row() != -1)
        mainTable->setCurrentIndex(row);

поменял строки местами, и всё работает, но если можно расскажите как это лудше организовать.


Название: Re: QSqlQueryModel как правильно обновить
Отправлено: break от Август 09, 2009, 18:58
Может быть так:

Ведь форма редактирования принимает в качестве параметра что-то? У вас навреное ID записи из таблицы? Можно передавать ей указатель на модель, и индекс записи в модели которую нужно редактировать. Форма редактирования меняет данные прямо в модели (но не в БД) и так со всеми записями, соответственно в табличке без переоткрытия после закрытия формы редактирования данные должны обновится. А когда уже будет закрыто окошко таблицы (или пользователь нажмет кнопку "применить изменения"), то данные из модели должны перенестись в БД. У вас вызывается хранимая процедура - предположим что без нее нельзя обойтись, но можно создать триггер в БД onUpdate где и будет вызываться эта процедура - соответственно при подтверждении данных (отправке изменений) этот триггер будет вызван для всех измененных записей.
В качестве модели надо либо использовать QSqlQueryModel с параметром обновления данных onManualSubmit или написать свою модель - тогда еще больше возможностей в плане вызова хитрого SQL запроса или вообще своя модель не будет закрывать Query а отправлять изменения в БД другим запросом как бы синхронизируя то что есть в ней в БД. Вообще все мои варианты сводятся к "найти способ не переоткрывать запрос" может даже еще и попроще можно что-то придумать.


Название: Re: QSqlQueryModel как правильно обновить
Отправлено: ecspertiza от Август 10, 2009, 07:54
Спасибо поэкспериментирую.


Название: Re: QSqlQueryModel как правильно обновить
Отправлено: ranet от Октябрь 02, 2009, 10:15
Задача в следующем, есть форма добавления\редактирования есть таблица у неё есть контекстное меню, и вот например пользователь на одной из записи кликнул редактировать, открылась форма он что то изменил, потом кликнул Ок затем выполнилась хранимка в БД, а потом обновление таблицы, но нужно что бы указатель остался на том же месте сделал так
...
поменял строки местами, и всё работает, но если можно расскажите как это лудше организовать.

Я похожую задачу сколько-нибудь элегантно тоже не могу решить.. http://www.prog.org.ru/index.php?topic=8096.msg48534#msg48534 - там максимум, до чего смог додуматься. Вобщем это работает, да и народ вроде как одобрил:).. Но не красиво блин.. не нравится. С большим числом строк это наверное должно все же работать, хотя не проверял.. Уткнулся в другое: если таблиц много, то есть большой соблазн для работы с ними по очереди (а так вполне устраивает) использовать одну и ту же вьюху, модель, и маппер (диалоги редактирования можно привинчивать и отвинчивать - для разных таблиц они отличаются). И сделать так, чтобы нахождение и подсвечивание выполнялось как слот или просто функция например при вызове submit() для модели.. (чтобы этот код, будучи раз вставленым, работал для всех таблиц) Главная трудность - id вытащить до submit(), а поиск выполнить - после. Сохранять его в глобальной переменной не хочется - некрасиво, хотя написать такой слот и привинтить его например к beforeUpdate ( int row, QSqlRecord & record ) можно. Пока думаю..

Есть и правда большой соблазн обойтись без переоткрывания запроса :)