Название: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Март 12, 2012, 16:50 MSSQL 2005, Qt 4.8, QODBC
Имеется хранимая процедура простого содержания: Код: select field1,field2 from SomeTable Отрабатывает без проблем. Изменяю текст процедуры на: Код: if 3=3 (IF 3=3 для примера, на самом деле любая проверка) Ошибок запроса нет, но и результата на клиенте нет тоже. При попытке тут же повторить запрос ответ "Подключение занято". [Microsoft][ODBC SQL Server Driver]Подключение занято до получения результатов для другого hstmt QODBC3: Unable to execute statement При этом другой клиент (не Qt) через ODBC в обоих случаях результат получает. В чём может быть проблема? Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Rem Norton от Март 13, 2012, 13:12 на чем чаще всего спотыкаются: чтобы получить данные из хранимой процедуры MSSQL надо QSqlQuery сказать setForwardOnly(true).
Чтобы корректно отпустить HSTMT надо сделать QSqlQuery::finish(); А если хочется правильное решение и сразу, то к сообщению прикладывай собираемый проект. Так ошибки находятся гораздо быстрее. Название: Re: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Март 13, 2012, 14:04 надо QSqlQuery сказать setForwardOnly(true). да говорил и то и другое :)Чтобы корректно отпустить HSTMT надо сделать QSqlQuery::finish(); проект прикладываю там же скрипты ХП и таблицы Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Rem Norton от Март 14, 2012, 00:05 Ошибка в этом:
Код
Точнее не то, чтобы ошибка, скорее "фича" Qt. Дело в том, что QSqlQueryModel не работает с forward-only запросами. Название: Re: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Март 14, 2012, 08:58 Цитата: Rem Norton QSqlQueryModel не работает с forward-only запросами. Хорошо. Но вот только одно "но" - как только я убираю управляющую конструкцию в хранимой процедуре (или IF или SET NOCOUNT), то всё работает замечательно. И ещё - я провёл аналогичный эксперимент с Adaptive Server Anywhere 8.02 (Sybase ASA) через тот же QODBC с аналогичной процедурой - всё отлично отрабатывает. Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Rem Norton от Март 14, 2012, 19:32 Ок, тогда сделай так:
Код
и посмотри, что напишет в консоли. Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Странник от Март 14, 2012, 21:24 наступал на такую граблю, долго бился. выполнение хранимой процедуры прерывалось на середине - и ни ошибок, ни результата. что помогло сейчас помню очень смутно, вроде на форуме где-то была тема. и завтра на работе код поковыряю.
Название: Re: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Март 16, 2012, 13:45 Цитата: Rem Norton Код и посмотри, что напишет в консоли. Так всё таки - при отключении управляющих конструкций результат перестаёт быть forward-only? При чём настройка setForwardOnly(true) игнорируется... Или как? Почему тогда с ASA 8.02 через QODBC нет ни каких проблем? Цитата: Странник что помогло сейчас помню очень смутно очень бы хотелось найти объяснение...Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Rem Norton от Март 17, 2012, 01:56 При отключении управляющих конструкций процедура перестает быть T-SQL. И дело не в ODBC, а в MS SQL.
Название: Re: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Апрель 13, 2012, 11:45 Спустя ровно месяц удалось вернуться к вопросу :)
Цитата: Rem Norton QSqlQueryModel не работает с forward-only запросами. Сделал я собственную модель...В общем проблема осталась. Дело не в forward-only. MS SQL не возвращает результат, точнее numRowsAffected() равен -1 - "cannot be determined" Цитата: Rem Norton При отключении управляющих конструкций процедура перестает быть T-SQL. Не хочу спорить - но хранимая процедура MS SQL в любом случае T-SQL (ну или тот диалект, который используется конкретным сервером, скажем PL/SQL или Watcom). И как бы управляющие конструкции в виде IF'ов и прочего и есть собственно язык SQL. Цитата: Rem Norton И дело не в ODBC, а в MS SQL. И получается, похоже по всему, что проблема таки в QODBC. Поскольку именно QODBC прослойка к основному ODBC и тот же Visual FoxPro не имеет проблем с получением результата от сервера не смотря на наличие или отсутствие управляющих конструкций. Для тех, кто хочет как-то разобраться в ситуации, прикладываю проект. Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Странник от Апрель 13, 2012, 15:02 проверил на MS SQL 2005, драйвера SQL Server и SQL Native Client, Qt 4.8.1. хранимая процедура выполняется и возвращает верный результат. минимальный рабочий пример:
Код: QSqlQuery sqlQuery; Название: Re: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Апрель 13, 2012, 16:48 Цитата: Странник хранимая процедура выполняется и возвращает верный результат в смысле exec отрабатывает без ошибки или видны результаты запроса?и if 3=3 в коде процедуре не закомментарен? Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Странник от Апрель 13, 2012, 18:08 в смысле exec отрабатывает без ошибки или видны результаты запроса? и exec() отрабатывает, и результаты запроса видны. if 3=3 на месте. более того, в моих проектах на том же MS SQL 2005 в аналогичных случаях никаких проблем не возникало. была трабла с запросами, возвращающими множественный резалтсет, но у вас явно не тот случай.и if 3=3 в коде процедуре не закомментарен? предлагаю вам собрать демо-проект sqlbrowser и попробовать выполнить через него запрос: Код: {CALL teststoreproc (2)} Код: EXEC teststoreproc 2 Название: Re: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Апрель 14, 2012, 11:48 Цитата: Странник предлагаю вам собрать демо-проект sqlbrowser и попробовать выполнить через него запрос: Код: {CALL teststoreproc (2)} Код: EXEC teststoreproc 2 эксперимент произведён :) результат тот же - при наличии IF'а - "Forward-only queries cannot be used in a data model" попытка тут же повторно выполнить exec даёт: [Microsoft][ODBC SQL Server Driver]Подключение занято до получения результатов для другого hstmt QODBC3: Unable to execute statement скриншоты прилагаю (http://narod.ru/disk/46059257001.64e168cd43a169ab1b826f55caadae10/jpg.zip.html) информация о системе (клиент): Microsoft SQL Server Management Studio 9.00.1399.00 Microsoft Analysis Services Client Tools 2005.090.1399.00 Microsoft Data Access Components (MDAC) 2000.085.1132.00 (xpsp.080413-0852) Microsoft MSXML 2.6 3.0 5.0 6.0 Operating System 5.1.2600 сервер: Product Microsoft SQL Server Standard Edition Operating System Microsoft Windows NT 5.2 (3790) Version 9.00.4262.00 самое интересное - я проверял на MS SQL 2000 в совершенно другой сети - результат был аналогичный правда ещё на QSqlTableModel а не на собственной Цитировать и exec() отрабатывает, и результаты запроса видны. if 3=3 на месте ума не приложу - что же я не так делаю то?...Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Странник от Апрель 14, 2012, 13:16 прошу прощения, у вас проблема с выполннием запроса или все-таки с моделью? если с моделью, то ответ уже был получен вами ранее: QSqlQueryModel не поддерживает forward-only запросов. isForwardOnly возвращает актуальное состояние резалтсета, а не значение, установленное в setForwardOnly. то есть, MS SQL Server возвращает forward only результат, на чем QSqlQueryModel и затыкается.
почему не работает ваша собственная реализация, давайте разбираться. с ходу вижу, что у вас неверно реализовано добавление данных в модель. не используйте size() или numRowsAffected() для определения числа записей, надежнее крутиться в while(mQuery.next()). Название: Re: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Апрель 14, 2012, 15:14 Цитировать проблема с выполннием запроса или все-таки с моделью? с выполнением запроса из Management Stidio нет ни каких проблем, в любом виде процедура отрабатывает (скриншоты приводил)как советовали - я из демо sqlbrowser пытался проверять вызов процедуры о результатах эксперимента с sqlbrowser доложил само собой, в sqlbrowser используется QSqlQueryModel - но Вы же утверждаете, что у Вас Цитировать и exec() отрабатывает, и результаты запроса видны. if 3=3 на месте. проверил на MS SQL 2005, драйвера SQL Server и SQL Native Client, Qt 4.8.1. поскольку Цитировать MS SQL Server возвращает forward only результат, на чем QSqlQueryModel и затыкается. я и решил использовать свою модельно как оказалось, дело не в forward only результате о чём выше написал, что проблема осталась Цитировать почему не работает ваша собственная реализация, давайте разбираться. с ходу вижу, что у вас неверно реализовано добавление данных в модель. не используйте size() или numRowsAffected() для определения числа записей, надежнее крутиться в while(mQuery.next()). моя реализация вполне работаетвот только до тех пор пока нет пресловутой "управляющей конструкции" :) size() я не использую - поскольку MS SQL его не поддерживает - просто код использовался и для других серверов, и закомментарен сейчас numRowsAffected() вполне работоспособен на MS SQL - но сейчас я тоже его исключил ориентируюсь исключительно на next() НО как только я раскомментариваю if 3=3 или SET NOCOUNT ON возвращаемый на Qt клиента результат запроса не содержит ни одной записи вот в чём проблема и я ни как не могу понять причины этого сейчас установил MS SQL 2005 Express на рабочую станцию - результат не изменился Название: Re: MSSQL 2005 Хранимая процедура Отправлено: Странник от Апрель 15, 2012, 19:49 в самом деле, любопытно. что имеется у меня на MS SQL Express 2005:
- запрос успешно выполняется и при отсутствии, и при наличии управляющих инструкций в хранимой процедуре. результат запроса доступен в QSqlQuery в обоих случаях - при наличии управляющих инструкций QSqlQuery::isForwardOnly() возвращает true - numRowsAffected() возвращает -1 (первый затык вашей модели в setQuery), заменяем на while(mQuery.next()) затем ваша модель у меня затыкается на setData (value содержит верные данные из запроса, а index не валиден), дальше пока не копал. завтра попробую повторить эксперимент на другом сервере, вдруг там запрос не сработает. Название: Re: MSSQL 2005 Хранимая процедура Отправлено: chagovets от Апрель 16, 2012, 08:05 Орешек знаний тверд
Но все же, мы не привыкли отступать! Странник, Вы были правы! Цитата: Странник надежнее крутиться в while(mQuery.next()). я хоть и писал чтоЦитировать numRowsAffected() вполне работоспособен на MS SQL - но сейчас я тоже его исключил но исключил не до концаориентируюсь исключительно на next() в общем если действительно идти по next() всё встало на свои места премного благодарен Страннику за наставление на путь истинный ;) P.S. MS SQL впечатляет в плохом смысле :) |