Название: [4.4.1] UNION и bindValue Отправлено: Пантер от Сентябрь 04, 2008, 16:45 Протр*CENSORED*ся сегодня с одним запросом. В общем вот его упрощенная форма:
Код: SELECT id,pole1 За 4 часа экспериментов было выявлено, что если сделать: Код: SELECT id,pole1 bindValue(":id",value) bindValue(":id1",value) Все работает как часы. Это баг или фича? БД=FireBerd DRIVER=QIBASE Название: Re: [4.4.1] UNION и bindValue Отправлено: developer от Сентябрь 05, 2008, 13:37 Мне кажеться что UNION несколько устарелый запрос, лучше использовать JOIN-ы. Возможно тогда не будет проблем
Название: Re: [4.4.1] UNION и bindValue Отправлено: Пантер от Сентябрь 05, 2008, 17:58 Да не важно что устарело, а что нет. Есть стандарт sql и его должны подерживать. Тут другой вопрос: кто прав?
Название: Re: [4.4.1] UNION и bindValue Отправлено: Alex03 от Сентябрь 07, 2008, 12:52 Название: Re: [4.4.1] UNION и bindValue Отправлено: Alex03 от Сентябрь 07, 2008, 12:57 Мне кажеться что UNION несколько устарелый запрос, лучше использовать JOIN-ы. Возможно тогда не будет проблем developer А приведите ка запрос с JOIN, функционально аналогичный запросу panter_dsd?Название: Re: [4.4.1] UNION и bindValue Отправлено: Пантер от Сентябрь 07, 2008, 15:07 Раз фича, то можешь хоть одно объяснение ей придумать? Что-то у меня не получается.
Название: Re: [4.4.1] UNION и bindValue Отправлено: Tonal от Сентябрь 07, 2008, 22:41 А ты на реализацию bindValue посмотри - там вроде всё прозрачно. :)
Название: Re: [4.4.1] UNION и bindValue Отправлено: Alex03 от Сентябрь 08, 2008, 05:46 Скорее фича. :) Раз фича, то можешь хоть одно объяснение ей придумать? Что-то у меня не получается.фича -> feature -> особенность Объяснения... проще реализация (небольшой выйгрыш по скорости/размеру кода), c Sql::Out две переменные в запросе с одним и тем же именем - считай ошибка проектирования. Хотя конечно если б тролли добавили в код немного искусственного интелекта было бы не плохо. :) Название: Re: [4.4.1] UNION и bindValue Отправлено: Tonal от Сентябрь 08, 2008, 07:50 Таки судя по всему баг.
Посмотрев на код QSqlResult::exec() можно заметить, что идёт тупая замена в строке запроса имён параметров на значения. Находят первое вхождение параметра и заменяют. Если дописать 2 строчки, можно заменить все вхождения. С другой стороны, должен выполнятся не QSqlResult::exec() а exec() соответствующего драйвера, но Firebird не поддерживает именованные параметры в запросах напрямую, так что разумно предположить, что где-то делается та же, или похожая, замена (кода с ходу не нашел)... Название: Re: [4.4.1] UNION и bindValue Отправлено: Alex03 от Сентябрь 08, 2008, 08:45 Таки судя по всему баг. QSqlResult - абстрактный класс, и exec() в нём определён для СУБД не поддерживающих QSqlDriver::PreparedQueries.Посмотрев на код QSqlResult::exec() можно заметить, что идёт тупая замена в строке запроса имён параметров на значения. Находят первое вхождение параметра и заменяют. Если дописать 2 строчки, можно заменить все вхождения. С другой стороны, должен выполнятся не QSqlResult::exec() а exec() соответствующего драйвера, но Firebird не поддерживает именованные параметры в запросах напрямую, так что разумно предположить, что где-то делается та же, или похожая, замена (кода с ходу не нашел)... В случае же с IB/FB имеем: Код: class Q_SQL_EXPORT QSqlCachedResult: public QSqlResult ... Название: Re: [4.4.1] UNION и bindValue Отправлено: Tonal от Сентябрь 08, 2008, 10:47 Это понятно. Ты можешь указать где там код, который отвечает за биндинг по имени?
Ведь Firebird его не поддерживает - значит Qt должно как-то его само обрабатывать. Название: Re: [4.4.1] UNION и bindValue Отправлено: Alex03 от Сентябрь 08, 2008, 12:20 Это понятно. Ты можешь указать где там код, который отвечает за биндинг по имени? Ведь Firebird его не поддерживает - значит Qt должно как-то его само обрабатывать. QSqlResult::BindValue()/addBindValue() строят в памяти соотношения имён/позиций со значениями. bool QSqlResult::savePrepare(const QString& query) разруливает тот или иной способ задания параметров, модифицирует, если надо, текст запроса, изменяя :Var1 на ? и наоборот. Ну а в случае если драйвер не имеет QSqlDriver::PreparedQueries (или не переопределён prepare()), то вызывается дефолтный prepare(), который по сути готовит данные для дефолтного exec(), который в свою очередь подставляет в запрос непосредсдвенные значения переменных. Драйвер-ы БД могут вызывать чтото из Код: QVariant QSqlResult::boundValue(int index) const Как пример, в QIBaseResult::exec() вызывается boundValues(); |