Russian Qt Forum
Ноябрь 23, 2024, 08:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: PyQt4 + SQLite. QtSql.QSqlQuery.bindvalue и Null  (Прочитано 6024 раз)
Пытон
Гость
« : Июль 29, 2015, 11:23 »

Моя программа получает данные из одной таблицы: FAM, IM, OT
А затем делает выборку на каждую персону из другой таблицы, при этом
Код
Python
queryFIO = QtSql.QSqlQuery(connection)
queryFIO.exec("SELECT FAM, IM, OT FROM FIOTABLE")
queryBBB = QtSql.QSqlQuery(connection)
queryBBBtext = "SELECT BUM, BAM, BOM FROM BUMTABLE WHERE FAM = ? and IM = ? and OT = ?"
while queryFIO.next():
 record = query.record()
 A_FAM = record.value("FAM")
 A_IM = record.value("IM")
 A_OT = record.value("OT")
 queryBBB.prepare(queryBBBtext)
 queryBBB.bindValue(A_FAM)
 queryBBB.bindValue(A_IM)
 queryBBB.bindValue(A_OT)
 queryBBB.exec_()
 

Если в FIOTABLE, допустим, поле FAM содержит Null, то в соответствующий A_FAM запишется PyQt4.QtCore.QPyNullVariant object, который НИФИГА не равен себе подобным, если получен из других полей или строк БД.
Т.е. queryBBB не найдёт такие же FAM, IM, OT во второй таблице.

Как прибиндить null???

Можно сделать проверку
type(record.value(“FAM”)) == QtCore.QPyNullVariant
а дальше что?
Что вместо этого QtCore.QPyNullVariant биндить в соответствующее поле, чтобы итоговый SQL был равнозначен:
SELECT BUM, BAM, BOM FROM BUMTABLE WHERE FAM = Null, IM = “БОБЁР”, OT = “БОБРОВИЧ”
« Последнее редактирование: Июль 29, 2015, 14:46 от Пытон » Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #1 : Июль 29, 2015, 12:18 »

SELECT BUM, BAM, BOM FROM BUMTABLE WHERE FAM = Null, IM = “БОБЁР”, OT = “БОБРОВИЧ”
Результат подобного запроса не предсказуем.
Любой эскуэльщик вам скажет, что = null неправильно, надо писать is null.
Но это все лирика...

А по задаче: я бы обошелся одним грамотным запросом по двум таблицам.
Записан
Пытон
Гость
« Ответ #2 : Июль 29, 2015, 12:51 »

Количество полей, по совпадению которых нужно делать выборку, может быть различным.
Пример упрощен.
В реале там сперва создаётся питоновский список списков из имён полей и их значений, чтобы, используя его, биндить нужные значения.

А два запроса у меня потому, что данные пишутся в два текстовых файла. Типа выгрузки или экспорта. В одном уникальные Ф.И.О в другом соответствующие каждому Ф.И.О поля из второй таблицы.
« Последнее редактирование: Июль 29, 2015, 12:54 от Пытон » Записан
Пытон
Гость
« Ответ #3 : Июль 29, 2015, 14:49 »

Мысленно плюнул в монитор, мысленно снеся его со стола, и стал генерировать строку запроса, перед тем как прибиндить туда значения.
queryBBBtext = "SELECT BUM, BAM, BOM FROM BUMTABLE WHERE FAM is Null and IM = ? and OT = ?"

Т.е. теперь те значения, которые содержат этот чёртов Null, более никуда не биндятся. Изменяется сам текст SQL-запроса для prepare.
Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #4 : Июль 29, 2015, 19:48 »

Мысленно плюнул в монитор, мысленно снеся его со стола, и стал генерировать строку запроса, перед тем как прибиндить туда значения.
queryBBBtext = "SELECT BUM, BAM, BOM FROM BUMTABLE WHERE FAM is Null and IM = ? and OT = ?"

Т.е. теперь те значения, которые содержат этот чёртов Null, более никуда не биндятся. Изменяется сам текст SQL-запроса для prepare.

А почему не
SELECT BUM, BAM, BOM FROM BUMTABLE
 WHERE (:fam is null OR FAM = :fam)
    AND (:im is null OR IM = :im)
    AND (:ot is null OR OT = :ot)
?
и биндить по именам, а не по "?"
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #5 : Июль 29, 2015, 23:51 »

А почему не
SELECT BUM, BAM, BOM FROM BUMTABLE
 WHERE (:fam is null OR FAM = :fam)
    AND (:im is null OR IM = :im)
    AND (:ot is null OR OT = :ot)
?
и биндить по именам, а не по "?"
в документации к qt4 написано:
Код:
Values cannot be bound to multiple locations in the query, eg:
INSERT INTO testtable (id, name, samename) VALUES (:id, :name, :name)
Binding to name will bind to the first :name, but not the second.

в qt5 не написано, стоит проверить
Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #6 : Июль 30, 2015, 11:20 »

А почему не
SELECT BUM, BAM, BOM FROM BUMTABLE
 WHERE (:fam is null OR FAM = :fam)
    AND (:im is null OR IM = :im)
    AND (:ot is null OR OT = :ot)
?
и биндить по именам, а не по "?"
в документации к qt4 написано:
Код:

Values cannot be bound to multiple locations in the query, eg:
INSERT INTO testtable (id, name, samename) VALUES (:id, :name, :name)
Binding to name will bind to the first :name, but not the second.

в qt5 не написано, стоит проверить

Вообще, странно. По идее биндинг должен осуществляться средствами БД.
По собственному опыту, знаю что такое прокатывало с Oracle (QOCI) и для Qt4 и Qt5.
Но может для других драйверов такое не прокатит.

Не суть... Можно биндить одни и те же значения по разным именам.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.192 секунд. Запросов: 23.