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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Oracle Collections  (Прочитано 5907 раз)
Nimbus
Гость
« : Декабрь 22, 2010, 13:59 »

Доброго времени суток.
Передо мной стоит задача выборки из БД Oracle 10g большого объёма данных, которые имеют тип mdsys.sdo_geomerty
Как это реализовать средствами Qt, например, через классы QSqlQuery или QSqlQueryModel?
Записан
prometey
Гость
« Ответ #1 : Декабрь 22, 2010, 15:11 »

лучше это сделать через OCI
Записан
twp
Гость
« Ответ #2 : Декабрь 22, 2010, 15:29 »

QSqlQuery ибо QSqlQueryModel предназначен для отбражения результатов запроса в QTableView. Кроме того не известно как себя поведет QSqlQuery с таким типом данных, поскольку он по ходу не приводится к QVariant. Наверно действительно лучше юзать напрмую OCI или поискать специализированный драйвер для Oracle на С++
« Последнее редактирование: Декабрь 22, 2010, 15:32 от twp » Записан
Nimbus
Гость
« Ответ #3 : Декабрь 23, 2010, 12:36 »

Возможно, это уже не в тему, но кто имел с этим дело? Использовал OCCI, вроде удобно.
Взял объектное описание типов на C++ отсюда и их реализацию, реализовал привязку типов к методам 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'е, возвращает одну строку.
« Последнее редактирование: Декабрь 23, 2010, 12:52 от JC » Записан
twp
Гость
« Ответ #4 : Декабрь 23, 2010, 12:51 »

могу только посоветовать в начале проверять что возвращает
Код:
rs->next();
Записан
Nimbus
Гость
« Ответ #5 : Декабрь 23, 2010, 12:57 »

C rs всё нормально, уже проверял, что будет, если ничего не возвратит.
Тут проблема, по всей видимости, именно в описании/привязке классов к типам оракла. Только вот в чём соль я не могу понять... Уже 4 часа парюсь над этой проблемой. Делал по этому мануалу.
« Последнее редактирование: Декабрь 23, 2010, 12:59 от JC » Записан
twp
Гость
« Ответ #6 : Декабрь 23, 2010, 13:06 »

А сам объект SDOGeometry *geom валидный? если попробовать привести через dynamic_cast?
Записан
Nimbus
Гость
« Ответ #7 : Декабрь 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;
« Последнее редактирование: Декабрь 23, 2010, 13:38 от JC » Записан
Barmaglodd
Гость
« Ответ #8 : Декабрь 23, 2010, 13:45 »

Я работал через http://gdal.org. Проблем не было, плюсом единый интерфейс для многих источников пространственных данных.
Записан
twp
Гость
« Ответ #9 : Декабрь 23, 2010, 15:34 »

Через dynamic_cast - нет. Через static_cast работает. Что это значит?

т.е. при приведении через dynamic_cast  geom == 0?
в таком случае вероятно в выборке вместо объекта SDOGeometry * хранится что-то другое, но не SDOGeometry *
Записан
Nimbus
Гость
« Ответ #10 : Декабрь 24, 2010, 10:50 »

Короче, выяснил в чём проблема - при вызове метода readSQL из AnyData не может считаться коллекция в вектор. Использовал разные версии либ (компилил на VC9.0, к ней цеплял occi либу для vc7.1 - вектор заполнялся, но при вызове его метода size() он возвращал отрицательное значение, а с либой для vc9 он вообще вываливал сообщение об обращении к нулевой памяти). Кстати, vc9 доступна только с версией occi для 11g оракла, а цеплялся-то я к 10-ке. А так, если закомментировать чтение этих полей, то работает отлично, объекты классов корректны. За OCI браться не стал - слишком бородатая либа. Придётся на C# ваять Грустный
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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