Russian Qt Forum

Qt => Базы данных => Тема начата: Пытон от Июль 29, 2015, 11:23



Название: PyQt4 + SQLite. QtSql.QSqlQuery.bindvalue и Null
Отправлено: Пытон от Июль 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 = “БОБРОВИЧ”


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

А по задаче: я бы обошелся одним грамотным запросом по двум таблицам.


Название: Re: PyQt4 + SQLite. QtSql.QSqlQuery.bindvalue и Null
Отправлено: Пытон от Июль 29, 2015, 12:51
Количество полей, по совпадению которых нужно делать выборку, может быть различным.
Пример упрощен.
В реале там сперва создаётся питоновский список списков из имён полей и их значений, чтобы, используя его, биндить нужные значения.

А два запроса у меня потому, что данные пишутся в два текстовых файла. Типа выгрузки или экспорта. В одном уникальные Ф.И.О в другом соответствующие каждому Ф.И.О поля из второй таблицы.


Название: Re: PyQt4 + SQLite. QtSql.QSqlQuery.bindvalue и Null
Отправлено: Пытон от Июль 29, 2015, 14:49
Мысленно плюнул в монитор, мысленно снеся его со стола, и стал генерировать строку запроса, перед тем как прибиндить туда значения.
queryBBBtext = "SELECT BUM, BAM, BOM FROM BUMTABLE WHERE FAM is Null and IM = ? and OT = ?"

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


Название: Re: PyQt4 + SQLite. QtSql.QSqlQuery.bindvalue и Null
Отправлено: kai666_73 от Июль 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)
?
и биндить по именам, а не по "?"


Название: Re: PyQt4 + SQLite. QtSql.QSqlQuery.bindvalue и Null
Отправлено: Johnik от Июль 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 написано (http://doc.qt.io/qt-4.8/qsqlquery.html#bindValue):
Код:
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 не написано, стоит проверить


Название: Re: PyQt4 + SQLite. QtSql.QSqlQuery.bindvalue и Null
Отправлено: kai666_73 от Июль 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 написано (http://doc.qt.io/qt-4.8/qsqlquery.html#bindValue):
Код:

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.
Но может для других драйверов такое не прокатит.

Не суть... Можно биндить одни и те же значения по разным именам.