crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> просмотр таблицы с меняющимися данными, запоминание и выделение тек строки
Steklova Olga
  опции профиля:
сообщение 3.2.2012, 21:20
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Всем привет! ;)
Есть у меня две таблицы БД: T1 и T2, в каждой есть поля ID INTEGER (PK, автоинкрементное) и PARAM FLOAT. Для работы с таблицами использую QSqlTableModel и QTableView.

Во время работы программы в таблицу T1 записи только добавляются.
Организую заполнение и просмотр следующим образом:
- при поступлении первой записи добавляю ее в таблицу БД, выполняю select для модели, первую строку таблицы делаю текущей, запоминаю соотв. значение ID,
- при поступлении следующей записи добавляю ее в таблицу БД, выполняю select для модели, строку с запомненным ID делаю текущей, делаю скроллинг отображения для обеспечения видимости текущей строки,
- при изменении текущей строки оператором запоминаю значение ID. Тут все OK.

А вот с таблицей T2 посложнее...
Во время работы программы, периодически (вероятно, не чаще, чем 1 раз в 5 сек), для занесения в таблицу T2 приходит сразу целый массив записей (размер массива - от одной до 200 записей). Мне надо хранить в БД данные только последнего массива.
Данные разных массивов:
- могут полностью совпадать,
- могут отличаться всеми значениями,
- могут отличаться несколькими значениями,
- могут отличаться количеством значений.
Организую заполнение и просмотр следующим образом:
- при поступлении первого массива добавляю поступившие записи в таблицу БД, выполняю select для модели, первую строку таблицы делаю текущей,
- при поступлении следующего массива удаляю все записи из таблицы БД, добавляю поступившие записи в таблицу БД, выполняю select для модели, первую строку таблицы делаю текущей (пока так).

Как здесь просматривать таблицу с запоминанием и выделением текущей строки?
1) Запоминать ID текущей строки? Здесь это не поможет, так как поле автоинкрементное.
2) Сделать поле ID не автоинкрементным, не удалять предыдущий массив и добавлять новый, а обновлять массив? Этот вариант мне совсем не нравится, по-моему, он очень сложный.
3) Запоминать PARAM текущей строки, а при поступлении следующего массива искать в нем запись с запомненным PARAM и делать ее текущей? А если такая не найдется, то делать текущей первую. Но для этого придется сравнивать значения типа FLOAT, видимо используя какую-то точность сравнения. Или так и надо? :huh:
Других вариантов не придумала. У кого какие мысли есть по этому поводу? Спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Tonal
  опции профиля:
сообщение 10.2.2012, 12:00
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Т. е. с позиционированием ты разобралась. :)
Могу только добавить, что раз есть порядок, то можно позиционироваться на первый элемент больший или равный текущему или на последний меньший или равный, на выбор. :)

5. Неуказанное в insert-е поле заполняется значением по умолчанию для этого поля, которое можно указать при создании таблицы (или при создании домена). Если значение по умолчанию не указано, подставляется null.

6. Тут возможны варианты с транзакциями: сохраняется ли препарированность между транзакциями или для новой транзакции нужно препарить запросы по новой?
Если мне склероз не изменяет, Firebird в последних версиях не требовал переподготавливать запросы каждый раз, но не знаю как к этому относится драйвер в Qt.

7. Есть ещё вариант а' - использовать биндинг по имени или номеру. Тогда obj_id можно забиндить 1 раз перед циклом.
Я бы выбрал его. :)

8. Ну, если совсем втупую то примерно так (псевдокод на псевдопитоне):
# Где-то объявлен кеш запросов. Для С++ - QMap<QList<QString>, QSqlQuery>;
queryCach = {}

# Функция для сохранения записи в базу. Для C++ void updateRec(const tRec& rec);
def updateRec(rec):
  # Ключь состоит из списка имён ненулевых полей. Для С++ - QList<QString>
  keys = []
  # Список значений. Для С++ - QList<QVariant>
  vals = []
  if rec.param != null_double:
    keys.append('param')
    vals.append(rec.param)
  if rec.fint1 != null_qint32:
    keys.append('fint1')
    vals.append(rec.fint1)
  ... # то же самое для остальных полей

  # Вытаскиваем запрос по ключу
  query = queryCach.get(keys)
  # Если запроса нет в кеше - создаём и запоминаем:
  if query is None:
    # Каждое имя поле из текущего набора keys подставляем в строчку '%s = ?'
    # и сцепляем эти строчки через запятую
    sql_fld = ', '.join('%s = ?' % fld for fld in keys)
    # Подставляем строку с полями в шаблон запроса
    sql = 'update %s set %s where id = ?' % (table_name, sql_fld)
    query = QSqlQuery()
    query.prepare(sql)
    queryCach[keys] = query

  # Биндим значения и выполняем
  for val in vals:
    query.addBindValue(val)
  query.addBindValue(rec.id)
  query.exec()

Хотя можно вместо списка с QVariant использовать словарь и биндить по именам. :)
Главная идея, что сам запрос для конкретной конфигурации полей ты создаёшь только если она появилась и лишь один раз.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- Steklova Olga   просмотр таблицы с меняющимися данными, запоминание и выделение тек строки   3.2.2012, 21:20
- - ilyabvt   Цитата3) Запоминать PARAM текущей строки, а при по...   3.2.2012, 23:51
- - Steklova Olga   ЦитатаСравнивайте также как вы бы сравнивали целоч...   4.2.2012, 21:22
|- - ilyabvt   Цитата(Steklova Olga @ 5.2.2012, 0:22) Ци...   4.2.2012, 22:46
- - Steklova Olga   ЦитатаЯ не имел ввиду что нужно конвертировать в ц...   5.2.2012, 17:34
- - Steklova Olga   Однако не все так тривиально... 1) Зачем-то же на...   6.2.2012, 20:04
|- - Tonal   Цитата(Steklova Olga @ 7.2.2012, 0:04) Де...   7.2.2012, 8:11
- - Steklova Olga   1) ЦитатаИспользуйте биндинг переменныхПонятно, ка...   7.2.2012, 14:40
- - Tonal   1) Ты же вроде бы писала, что T2 ты очищаешь и вст...   8.2.2012, 8:51
- - Steklova Olga   Таблицы Т1 и Т2 - это один пример, таблица БД с п...   8.2.2012, 12:14
- - Tonal   Про Т2 и прзиционирование: Что-то я не очень понял...   9.2.2012, 9:45
- - Steklova Olga   Привет! Пишу на этот раз сразу несколько сооб...   9.2.2012, 21:04
- - Steklova Olga   09.02.2012 часть 3 5) Цитата(Tonal @ 9.2.2012...   10.2.2012, 10:14
- - Tonal   Т. е. с позиционированием ты разобралась. Могу то...   10.2.2012, 12:00
- - Steklova Olga   Привет! 6. Цитатасохраняется ли препарированн...   10.2.2012, 17:01


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.11.2024, 10:26