
Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
20.09.2005, 12:41
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Вопрос. Мы в приложении на С++ обращаемся к Oracle через OLE DB. Используется один и тот же ICommandText, в который по мере надобности сажается новый запрос. Так вот иногда при n-ном вызове ICommandText::SetCommandText возвращает DB_E_OBJECTOPEN. Вроде как Rowset открыт. При этом после скачивания данных всегда вызываются: hr = pIRowset->ReleaseRows( cRowsObtained,&rghRow, NULL, NULL, NULL ); hr = pIRowset->Release(); // output accessor hr = pIAccessor->ReleaseAccessor(hOutputAccessor,NULL); hr = pIAccessor->Release(); Чего ж им ещё нехватает? Сажать каждый раз пустой текст в ICommandText::SetCommandText помогло бы (ICommandText вернулся бы при этом в изначальное состояние), но мы этого делать не можем, потому что команду в некоторых случаях используют многократно. Есть ли какой-нибудь другой способ "закрыть" Rowset, не убив при этом команду? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
20.09.2005, 13:16
|
|||
|---|---|---|---|
|
|||
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Lana K. Сажать каждый раз пустой текст в ICommandText::SetCommandText помогло бы (ICommandText вернулся бы при этом в изначальное состояние), но мы этого делать не можем, потому что команду в некоторых случаях используют многократно. Есть ли какой-нибудь другой способ "закрыть" Rowset, не убив при этом команду? А что, нельзя команды для сохранения помещать, например, в CStringList? А при необходимости их "выковыривать" оттуда? А в ICommandText все-таки помещать пустую строку для его возвращения в первоначальное состояние... Это будет типа "истории команд" (как было в Norton Commander'е, FAR'e по набору Alt+F8) и пользователь сможет вызвать на исполнению любую из ранее набранных комманд... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
20.09.2005, 14:30
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Сажать пустую команду - это именно то, чего мне хотелось бы избежать. Приложение очень большое, состоит из нескольких программ (модулей). Недавно я столкнулась с тем, что в нескольких местах исходят из того, что команды "не обнуляются". Эти места я могла бы переделать, хотя очень не хочется :-(, но нет гарантии, что я все такие места отловлю. Поэтому я и ищу другой способ. Кроме того есть ещё один аргумент против такого решения: если сажать пустую строку, то команда, которая до этого уже была "подготовлена" у Oracle, должна будет при следующем вызове опять по новой готовиться. Тоже вроде как не очень красиво. Должен же существовать ещё какой-нибудь способ "закрыть" Rowset? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
20.09.2005, 14:45
|
|||
|---|---|---|---|
|
|||
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Lana K.Должен же существовать ещё какой-нибудь способ "закрыть" Rowset? Ну, можно, например, пересоздать объект pIRowset: Старый удалить по pIRowset.Release(), а затем снова сделать CreateInstance(....)... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
20.09.2005, 15:24
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Хм, ... и потом опять удалить? Спасибо, я попробую. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
20.09.2005, 17:56
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Ну а в документации слабо посмотреть, да? Специальная глава для вас написана. OLE DB Programmer's Reference Releasing Rowsets When the consumer is done with the rowset, it must release it as follows: If the consumer has created any accessors on the rowset, it must release them by calling IAccessor::ReleaseAccessor on each accessor individually. To release the rowset object itself, the consumer must call IUnknown::Release on each interface pointer retrieved on the rowset. When the rowset is released, it forces the release of any remaining row handles the consumer holds. Such handle objects are subordinate to the rowset and cannot cause it to linger beyond the point where all the interfaces for the rowset have been released. The rowset is responsible for cleaning up all such subordinate objects. Note If the consumer obtained the rowset by executing a command containing output parameters and the provider populates output parameters when the rowset is released (that is, the value of DBPROP_OUTPUTPARAMETERAVAILABILITY is DBPROP_OA_ATROWRELEASE), the consumer must ensure that memory allocated for the output parameters that were bound at ICommand::Execute time must still be valid when the rowset is released. Not doing so is a serious programming error that can cause abnormal termination. This topic is a part of: Chapter 4: Rowsets ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
22.09.2005, 15:22
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
2 Станислав C. К сожалению не получилось. Если команда уже посажена, то просто так от балды Rowset создать не получится. Т. е. и Accessor-ы соответствовать команде должны и тд. и тп. В результате та же петрушка. Есть ли хотя бы какая-нибудь возможность узнать, что там именно висеть остаётся? Например до Release-ания Rowset-а проверить, жив ли ещё какой- нибудь его Accessor? (А в идеале- ещё и какой именно?) 2 White Owl Спасибо большооое за информацию. Не поверите: уже читала. А вот вы вопрос читали? Проблема именно в том, что вроде как на первый взгляд всё корректно удаляется. И на второй взгляд, и на десятый тоже. Что-то всё-таки остаётся - судя по DB_E_OBJECTOPEN в какой-то момент. Что именно остаётся - пока словить не получилось. Мои предшественники судя по комментариям в кодах с этой проблемой сталкивались и вышли из положения просто: сажали каждый раз пустой текст в ICommandText::SetCommandText. Это переводит команду в изначальное состояние и снимает все проблемы. По причинам, которые я описала выше, мне приходится сейчас это переделывать. Так что если у вас по теме идеи будут, то буду очень благодарна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
22.09.2005, 17:43
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Некрасиво, но работает: Код: plaintext 1. 2. 3. 4. 5. 6. Мою проблему это решает: команда не обнуляется, но и ошибка "DB_E_OBJECTOPEN" больше не вылезает. Конечно Prepare каждый раз по-новой делать надо, что не есть гуд. Что интересно: ICommandPrepare::Unprepare() тоже DB_E_OBJECTOPEN должна бы вернуть если Rowset открыт, но этого не делает. Молчит как рыба об лёд, в смысле S_OK возвращает. А если Unprepare не вызываю, то DB_E_OBJECTOPEN рано или поздно при ICommandText::SetCommandText вылезает. Хм. Не ндравится мне это... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
22.09.2005, 18:31
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Lana K.Спасибо большооое за информацию. Не поверите: уже читала. Читала, да недостаточно внимательно :) When the rowset is released, it forces the release of any remaining row handles the consumer holds. Such handle objects are subordinate to the rowset and cannot cause it to linger beyond the point where all the interfaces for the rowset have been released. The rowset is responsible for cleaning up all such subordinate objects. То есть сначала освобождаем plAccessor, а потом plRowSet. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
22.09.2005, 18:49
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
2 White Owl Упс, претензии по-поводу непрочитанного вопроса снимаются, звиняйте. :-) Теперь поняла, к чему была цитата. Но по теме: это я в вопрос неаккуратно вставила, случайно в неправильном порядке. На самом деле сперва освобождаются Accessor-ы (все что есть, например и параметровые, и строковые и т.д.). И сами строки освобождаются совсем в другом месте, по мере загрузки. А вот IRowset::Release уже после всего этого вызывается. Так что проблема не в этом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
23.09.2005, 18:43
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Lana K.И сами строки освобождаются совсем в другом месте, по мере загрузки. А вот IRowset::Release уже после всего этого вызывается. Если у вас такое размазаное по коду освобождение ресурсов, то это очень не хорошо. Скорее всего, где-то происходит исключение и управление просто перепрыгивает через команды освобождения внутренних структур. Это кстати объясняет и почему ошибка появляется не всегда. Я бы, в первую очередь сейчас, облазил тот кусок кода который по идее должен бы освобождать внутренние ресурсы. И поискал бы там команду которая может выдвать исключение не отлавливаемого типа. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
23.09.2005, 19:37
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
White OwlЕсли у вас такое размазаное по коду освобождение ресурсов, то это очень не хорошо. Эт точно. Только у нас ещё много чего нехорошего, всего не переделаешь :-(. Но я нашла ситуацию, в которой эта ошибка воспроизводится стопроцентно. В отладчике всё многократно проиграла: все места с освобождением чего-либо вызываются, причем в нужном порядке, и возвращается всегда полный ОК. И не смотря на это потом DB_E_OBJECTOPEN вылезает. Я всё-таки подозреваю, что енто глюк, а разбираться с этим по-серьёзному времени у меня мало. Я и так за последние пару месяцев 2 баги по OLE DB на оракле открыть заставила, и каждый раз с бизнес кейсом, тестовыми оболочками и километровыми переговорами с саппортом. Надоели. Почему я думаю, что это глюк. 1. Вроде с виду всё правильно выполняется. 2. Когда я встроила вызов pICommandPrepare->Unprepare, он по идее должен был бы в том же самом месте тоже DB_E_OBJECTOPEN вернуть, если бы не всё освобождалось бы, или? А отрабатывается всё с ОК. 3. Я уже когда-то сталкивалась с таким же явлением в маленькой тестовой программке, не имеющей к нашей махине никакого отношения. Программку эту я тогда для совсем другой цели делала, на эту проблему тоже времени терять не хотелось и я просто чтобы не возиться сбивала каждый раз команду на пустой текст (там это не мешало). К сожалению програмку найти сейчас не смогла. Потом вот столкнулась с тем, что не я одна такая хитрая. Но только вот в нашей махине это "обнуление" боком вылезало, пришлось переделывать. Логично? (вопрос в основном про пункт 2) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
23.09.2005, 19:55
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
Lana K.2. Когда я встроила вызов pICommandPrepare->Unprepare, он по идее должен был бы в том же самом месте тоже DB_E_OBJECTOPEN вернуть, если бы не всё освобождалось бы, или? А отрабатывается всё с ОК. ... Логично? (вопрос в основном про пункт 2) Не совсем логично. ICommandPrepare::Unprepare не будет работать вообще если по каким-то причинам команда была запущена без предварительного ICommandPrepare::Prepare. То есть она может проверить флаг подготовленности - нет флага, сразу выходим не проверяя открыт резалт-сет или нет. Это поведение конечно будет различаться в разных драйверах, но.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
26.09.2005, 16:36
|
|||
|---|---|---|---|
Oracle OLE DB, DB_E_OBJECTOPEN, как закрыть Rowset? |
|||
|
#18+
White Owl Lana K.2. Когда я встроила вызов pICommandPrepare->Unprepare, он по идее должен был бы в том же самом месте тоже DB_E_OBJECTOPEN вернуть, если бы не всё освобождалось бы, или? А отрабатывается всё с ОК. Не совсем логично. ICommandPrepare::Unprepare не будет работать вообще если по каким-то причинам команда была запущена без предварительного ICommandPrepare::Prepare. То есть она может проверить флаг подготовленности - нет флага, сразу выходим не проверяя открыт резалт-сет или нет. Это поведение конечно будет различаться в разных драйверах, но.... Могло бы быть и так. Но поведение программы врят ли бы так от вызова ICommandPrepare::Unprepare изменилось бы, если там ничего не происходило. А факт налицо: после вызова ICommandPrepare::Unprepare ошибка больше не вылезает. Но я несмотря на эти соображения ещё раз всё облазила и внимательно в отладчике прокрутила. ICommandPrepare::Prepare вызывается. И отрабатывается всё без ошибок. Так что если у вас есть другие идеи, сомнения и примечания, то всегда пожалуйста. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/topic.php?fid=57&tablet=1&tid=2032729]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
49ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
49ms |
get tp. blocked users: |
2ms |
| others: | 233ms |
| total: | 376ms |

| 0 / 0 |
