|
|
|
Правильное заведение и освобождение STMT (ODBC)
|
|||
|---|---|---|---|
|
#18+
Не могу найти нормальной литературы по ODBC(что-бы понять как он работает, а не только синтаксис и описание функций, что есть в MSDN). Есть такой вопросик: На каждый запрос надо сначала алокейтить STMT( SQLAlloceHandle() ) и затем освобождать ( SQLFreeHandle() ). Т.е.: SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); SQLExecDirect( hStmt, TextStatement, sizeof(TextStatement) ); SQLFreeHandle(SQL_HANDLE_STMT, hStmt); Если я буду делать следующий запрос предварительно не сделав SQLFreeHandle(), т.е. например так: SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); SQLExecDirect( hStmt, TextStatement, sizeof(TextStatement) ); SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); SQLExecDirect( hStmt, TextStatement, sizeof(TextStatement) ); SQLFreeHandle(SQL_HANDLE_STMT, hStmt); И только в конце освобожу его. Что может быть плохого? Что может быть плохого, если запрос с резалт-сетом(заберу резалт-сет, и не освобождая STMT снова сделаю запрос) ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 18:15 |
|
||
|
Правильное заведение и освобождение STMT (ODBC)
|
|||
|---|---|---|---|
|
#18+
Eugene7Есть такой вопросик: На каждый запрос надо сначала алокейтить STMT( SQLAlloceHandle() ) и затем освобождать ( SQLFreeHandle() ). Нет. Не надо. Запускаешь какую-то команду, дожидаешься ее завершения. Если команда вернула резалтсет закрываешь его через SQLCloseCursor(), и сразу кидаешь в освободившийся стейтмент новую команду. Достаточно сделать SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt) в начале программы, сразу после подключения к базе. А SQLFreeHandle(hStmt) звать только перед самым выходом, непосредственно перед SQLDisconnect(hDdbc). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 19:04 |
|
||
|
Правильное заведение и освобождение STMT (ODBC)
|
|||
|---|---|---|---|
|
#18+
Eugene7Если я буду делать следующий запрос предварительно не сделав SQLFreeHandle(), т.е. например так: SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); SQLExecDirect( hStmt, TextStatement, sizeof(TextStatement) ); SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); SQLExecDirect( hStmt, TextStatement, sizeof(TextStatement) ); SQLFreeHandle(SQL_HANDLE_STMT, hStmt); И только в конце освобожу его. Что может быть плохого? Что может быть плохого, если запрос с резалт-сетом(заберу резалт-сет, и не освобождая STMT снова сделаю запрос) ? Что может быть плохого? Ну например утечка памяти и расходование ресурсов сервера. Причем она не "может быть", а "уже есть" :) Каждый SQLAllocHandle запрашивает у системы некоторый блок памяти и у сервера БД тоже выделяется несколько ресурсов. Повторый вызов SQLAllocHandle в приведенном примере просто забывает о предыдущем блоке памяти и выделяет новый. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 19:10 |
|
||
|
Правильное заведение и освобождение STMT (ODBC)
|
|||
|---|---|---|---|
|
#18+
White Owl Запускаешь какую-то команду, дожидаешься ее завершения. Если команда вернула резалтсет закрываешь его через SQLCloseCursor(), и сразу кидаешь в освободившийся стейтмент новую команду. Хм... А под "дожидаешься ее завершения" что имелось ввиду? Разве SQLExecute/SQLExecDirect сразу возвращает управление не дождавшись завершения исполнения команды? Если так, то как определить, что она исполнилась? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 19:20 |
|
||
|
Правильное заведение и освобождение STMT (ODBC)
|
|||
|---|---|---|---|
|
#18+
Eugene7 White Owl Запускаешь какую-то команду, дожидаешься ее завершения. Если команда вернула резалтсет закрываешь его через SQLCloseCursor(), и сразу кидаешь в освободившийся стейтмент новую команду. Хм... А под "дожидаешься ее завершения" что имелось ввиду? Разве SQLExecute/SQLExecDirect сразу возвращает управление не дождавшись завершения исполнения команды? Если так, то как определить, что она исполнилась? По умолчанию они дожидаются завершения команды сервером. Но можно включить асинхронный режим. Смотри функцию SQLSetStmtAttr() и флаг SQL_ATTR_ASYNC_ENABLE. Тогда SQLExecute/SQLExecDirect будут посылать команду на сервер и сразу возвращаться с кодом SQL_STILL_EXECUTING. Все остальные команды выданые на этот стейтмент будут отпинываться с аналогичной ошибкой. Исполняющийся сервером стейтмент можно только отменить (SQLCancel) и посмотреть его статус (SQLGetDiagField и SQLGetDiagRec). Можно даже делать несколько тредов в своей программе работающих через один общий стейтмент, один тред вызывает SQLExecute() а второй сидит в цикле и ждет пока стейтмент осводиться, и быстро-быстро посылает свою собственную команду :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 19:45 |
|
||
|
Правильное заведение и освобождение STMT (ODBC)
|
|||
|---|---|---|---|
|
#18+
Спасибо Я так понимаю, если резалт-сет пустой, курсор все равно открываеться? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2006, 09:44 |
|
||
|
Правильное заведение и освобождение STMT (ODBC)
|
|||
|---|---|---|---|
|
#18+
Eugene7Спасибо Я так понимаю, если резалт-сет пустой, курсор все равно открываеться? Если команда в принципе должна возвращать резалт-сет, то да, курсор откроется. Если команда без резалтсета - курсор не откроется. То есть любой select создаст курсор, а update/insert не создаст. Открытие курсора на вызове хранимой процедуры зависит от хранимой процедуры, тут уже вопрос более сложный. Впрочем мы его обсуждали пару недель назад :) В принципе, можно слать SQLCloseCursor() всегда. Это не совсем красиво, но вполне безопасно. Если курсор был - он закроется, если курсора не было, ты получишь ошибку которую можно будет проигнорировать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2006, 17:48 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=33475048&tid=2032164]: |
0ms |
get settings: |
9ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
133ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
42ms |
get tp. blocked users: |
1ms |
| others: | 214ms |
| total: | 434ms |

| 0 / 0 |
