Russian Qt Forum

Qt => Базы данных => Тема начата: Nimbus от Декабрь 22, 2010, 13:59



Название: Oracle Collections
Отправлено: Nimbus от Декабрь 22, 2010, 13:59
Доброго времени суток.
Передо мной стоит задача выборки из БД Oracle 10g большого объёма данных, которые имеют тип mdsys.sdo_geomerty
Как это реализовать средствами Qt, например, через классы QSqlQuery или QSqlQueryModel?


Название: Re: Oracle Collections
Отправлено: prometey от Декабрь 22, 2010, 15:11
лучше это сделать через OCI


Название: Re: Oracle Collections
Отправлено: twp от Декабрь 22, 2010, 15:29
QSqlQuery ибо QSqlQueryModel предназначен для отбражения результатов запроса в QTableView. Кроме того не известно как себя поведет QSqlQuery с таким типом данных, поскольку он по ходу не приводится к QVariant. Наверно действительно лучше юзать напрмую OCI или поискать специализированный драйвер для Oracle на С++


Название: Re: Oracle Collections
Отправлено: Nimbus от Декабрь 23, 2010, 12:36
Возможно, это уже не в тему, но кто имел с этим дело? Использовал OCCI, вроде удобно.
Взял объектное описание типов на C++ отсюда (http://www.falconview.org/trac/FalconView/browser/Sandbox/mapnik-0.7.1/plugins/input/occi/spatial_classesh.h) и их реализацию, реализовал привязку типов к методам read/write, аля
Код
C++ (Qt)
void mapping(oracle::occi::Environment* envOCCI_) {
oracle::occi::Map *mapOCCI_ = envOCCI_->getMap();
mapOCCI_->put("MDSYS.SDO_GEOMETRY", &SDOPointType::readSQL, &SDOPointType::writeSQL);
mapOCCI_->put("MDSYS.SDO_POINT_TYPE", &SDOGeometry::readSQL, &SDOGeometry::writeSQL);
}
 

Далее в коде пишу
Код
C++ (Qt)
Environment *env = Environment::createEnvironment(Environment::OBJECT);
mapping(env);
Connection *conn = env->createConnection(ociLogin, ociPassword, ociConnectionString);
Statement* stmt = conn->createStatement("SELECT "
  " t.geoloc "
"FROM "
  "DATA_.METRICS t "
"WHERE "
  " t.graphid = '1092'" );
try {
ResultSet *rs = stmt->executeQuery();
rs->next();
SDOGeometry *geom = static_cast<SDOGeometry*>(rs->getObject(1));
 
}
catch (oracle::occi::SQLException &excep) {
std::cout << excep.getMessage();
}
 
stmt->closeResultSet(rs);
 
   env->terminateConnection(conn);
   Environment::terminateEnvironment(env);
 

Всё работает, всё собирается, но вот как только пытаюсь обращаться к методу geom->getSdo_point(); он возвращает указатель на SDOPointType, обращение к методам которого приводит к крэшу программы. Тут даже не оракловая ошибка, а ошибка обращения к памяти. Указатель вроде как не нулевой, но и некорректный тоже.
Кто с этим сталкивался?

З. Ы. добавил вывод на консоль в самом начале реализации методов
SDOGeometry::readSQL(oracle::occi::AnyData& streamOCCI_)
void *SDOGeometry::readSQL(void *ctxOCCI_)
void SDOGeometry::setSdo_point(SDOPointType * value)
И ни один не вызвался. Странно...
И да, я проверял этот запрос. Отрабатывается нормально на PL/SQL Developer'е, возвращает одну строку.


Название: Re: Oracle Collections
Отправлено: twp от Декабрь 23, 2010, 12:51
могу только посоветовать в начале проверять что возвращает
Код:
rs->next();


Название: Re: Oracle Collections
Отправлено: Nimbus от Декабрь 23, 2010, 12:57
C rs всё нормально, уже проверял, что будет, если ничего не возвратит.
Тут проблема, по всей видимости, именно в описании/привязке классов к типам оракла. Только вот в чём соль я не могу понять... Уже 4 часа парюсь над этой проблемой. Делал по этому мануалу (http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28390/objects.htm#i1001003).


Название: Re: Oracle Collections
Отправлено: twp от Декабрь 23, 2010, 13:06
А сам объект SDOGeometry *geom валидный? если попробовать привести через dynamic_cast?


Название: Re: Oracle Collections
Отправлено: Nimbus от Декабрь 23, 2010, 13:20
Через dynamic_cast - нет. Через static_cast работает. Что это значит?

Блин, ну хотя бы просто скажите как извлечь коллекцию данных, описанную как
Код
SQL
CREATE OR REPLACE TYPE MDSYS.SDO_ELEM_INFO_ARRAY AS VARRAY (1048576) of NUMBER
 
В SDOGeometry это поле описано как OCCI_STD_NAMESPACE::vector<oracle::occi::Number> SDO_ELEM_INFO;


Название: Re: Oracle Collections
Отправлено: Barmaglodd от Декабрь 23, 2010, 13:45
Я работал через http://gdal.org (http://gdal.org). Проблем не было, плюсом единый интерфейс для многих источников пространственных данных.


Название: Re: Oracle Collections
Отправлено: twp от Декабрь 23, 2010, 15:34
Через dynamic_cast - нет. Через static_cast работает. Что это значит?

т.е. при приведении через dynamic_cast  geom == 0?
в таком случае вероятно в выборке вместо объекта SDOGeometry * хранится что-то другое, но не SDOGeometry *


Название: Re: Oracle Collections
Отправлено: Nimbus от Декабрь 24, 2010, 10:50
Короче, выяснил в чём проблема - при вызове метода readSQL из AnyData не может считаться коллекция в вектор. Использовал разные версии либ (компилил на VC9.0, к ней цеплял occi либу для vc7.1 - вектор заполнялся, но при вызове его метода size() он возвращал отрицательное значение, а с либой для vc9 он вообще вываливал сообщение об обращении к нулевой памяти). Кстати, vc9 доступна только с версией occi для 11g оракла, а цеплялся-то я к 10-ке. А так, если закомментировать чтение этих полей, то работает отлично, объекты классов корректны. За OCI браться не стал - слишком бородатая либа. Придётся на C# ваять :(