powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Qt и MSSQL 2005
25 сообщений из 35, страница 1 из 2
Qt и MSSQL 2005
    #37701571
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MSSQL 2005, Qt 4.8, QODBC
Имеется хранимая процедура простого содержания:

Код: sql
1.
select field1,field2 from SomeTable



Отрабатывает без проблем.
Изменяю текст процедуры на:

Код: sql
1.
2.
if 3=3
	select field1,field2 from SomeTable




(IF 3=3 для примера, на самом деле любая проверка)
Ошибок запроса нет, но и результата на клиенте нет тоже.
При попытке тут же повторить запрос ответ "Подключение занято".

[Microsoft][ODBC SQL Server Driver]Подключение занято до получения результатов для другого hstmt QODBC3: Unable to execute statement


При этом другой клиент (не Qt) через ODBC в обоих случаях результат получает.
В чём может быть проблема?
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37701605
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема где-то в округе...
Показывай полностью текст процедуры и как ты ее вызываешь с клиента.
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702105
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
таблица:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TABLE [dbo].[SomeTable](
	[field1] [uniqueidentifier] NOT NULL DEFAULT (newid()),
	[field2] [varchar](50) COLLATE Cyrillic_General_CI_AS NOT NULL DEFAULT ('')
	
) ON [PRIMARY]

insert into SomeTable (field2) values ('test1')
insert into SomeTable (field2) values ('test2')
insert into SomeTable (field2) values ('test3')



код процедуры:
Код: sql
1.
2.
3.
4.
5.
6.
CREATE PROCEDURE [dbo].[teststorproc]
AS
BEGIN
if 3=3
	select * from SomeTable
END



код клиента:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
#include <QtCore>
#include <QtGui>
#include <QtSql>


int main(int argc, char *argv[])
{
    QTextCodec *codec = QTextCodec::codecForName("cp1251");
    QTextCodec::setCodecForTr(codec);

    QApplication app(argc, argv);

    QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");

    QString connString;
    connString="DRIVER={SQL Server};" ;
    connString=connString+"Server=servername;" ;
    connString=connString+"Database=dbname;" ;
    connString=connString+"Uid=user;Pwd=pass;";
    db.setDatabaseName(connString);

    if (db.open())
           QMessageBox::information(0,QObject::tr("Информация"),
                                    QObject::tr("Соединение установлено !"));
        else
            {
                QMessageBox::critical(0,
                                  QObject::tr("Ошибка"),
                                  QObject::tr("Не удалось подключиться к базе данных!\n")+
                                      QObject::tr("Ошибка :")+db.lastError().text()
                                  );
                 return 0;
            }

    QSqlQuery *mainQuery;
    QSqlQueryModel *viewModel;

    mainQuery = new QSqlQuery;
    viewModel = new QSqlQueryModel;

    QString sqlString;
    sqlString = "exec teststorproc";

    mainQuery->prepare(sqlString);
    mainQuery->setForwardOnly(true);
    mainQuery->exec();
    if (mainQuery->lastError().isValid())
        {
            QMessageBox::critical(0,
                              QObject::tr("Ошибка"),
                              QObject::tr("Ошибка запроса!\n")+
                                  QObject::tr("Ошибка :")+mainQuery->lastError().text()
                              );
            return 0;
        }
    viewModel->setQuery(*mainQuery);

    while (viewModel->canFetchMore())
        viewModel->fetchMore();

    QTableView *tblView;
    tblView = new QTableView;
    tblView->setSelectionMode(QAbstractItemView::SingleSelection);
    tblView->setModel(viewModel);
    tblView->show();

    return app.exec();
}
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702113
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> При этом другой клиент (не Qt) через ODBC в обоих случаях результат получает.
> В чём может быть проблема?


Поставь в процедуре в самом начале тела

set nocount on

ОБЯЗАТЛЬЕНО СООБЩИ РЕЗУЛЬТАТЫ !
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702125
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivset nocount on

это я пробовал с самого начала...
правда не придал значения - но результат тот же
т.е. даже если нет if'а а стоит SET NOCOUNT ON - на клиенте результата нет
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702135
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> это я пробовал с самого начала...
> правда не придал значения - но результат тот же
> т.е. даже если нет if'а а стоит SET NOCOUNT ON - на клиенте результата нет

???
Чего ?
Не должно такого быть.

Т.е. процедура, в ней --- голый SELECT 42 as val, скажем,
и возвращается набор, а если поставить перед этим
SET NOCOUNT ON

-- не возвращается ?

Проверь, пожалуйста.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702158
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
???
Чего ?
Не должно такого быть.

Т.е. процедура, в ней --- голый SELECT 42 as val, скажем,
и возвращается набор, а если поставить перед этим
SET NOCOUNT ON

-- не возвращается ?

именно так!
сегодня третий день с этим бьюсь :)
менял клиента - с VFP всё гуд
менял станцию клиента - Qt результат отрицательный
менял сервер - Qt результат отрицательный
удивлён не меньше...
до этого из под Qt с MSSQL не работал...
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702163
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 03/13/2012 11:50 AM, chagoserg wrote:

Несколько замечаний. Они могут повлиять, а могут и не повлиять на результат, но
всё равно надо так сделать.


sqlString = "exec teststorproc";

Это у тебя -- языковой запрос, его использовать бессмысленно.
Тебе лучше оформить вызов процедуры через RPC.
На ODBC это будет типа

sqlString = "{call teststorproc()}"; // не помню, нужны ли ()

при наличии параметров
sqlString = "{call teststorproc(?,?,?)}";

Также, если в QT выделено как-то общение с хранимыми процедурами отдельно,
типа класс не QQuery, а QProcedure, то лучше использовать этот класс (.
QProcedure).

> mainQuery->prepare(sqlString);

При вызове процедуры НЕ НАДО делать подготовленое выполнение,
не надо делать prepare. Разве что это -- какой-то вызов QT API , без
которого нельзя, в таком случае нужно убедится, что он делает
внутри, не делает ли вызов SQLPrepare (или как его там).

Внутри prepare создаёт из твоего запроса хранимую процедуру, которая у тебя
будет звать другую процедуру. Когда она уже у тебя есть, делать это бесссмысленно.

> mainQuery->setForwardOnly(true);

Если всё сделать так, как я говорю, то setForwardOnly(true); ставить не нужно,
оно и так будет само.

> mainQuery->exec();

В некоторых API различают выполнения запроса и открытие.
типа exec и open . exec -- для тех, которые не возвращают наборы данных,
open -- кто возвращает. Проверь, может ты неверный вызов испльзульешь.


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702219
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНесколько замечаний.
sqlString = "{call teststorproc}";

при наличии параметров
sqlString = "{call teststorproc(?,?,?)}";

всё это я пробовал...
результат одинаковый

MasterZiv mainQuery->prepare(sqlString);

prepare используется если биндятся параметры
это я тоже всё пробовал
наличие prepare на самом деле ни как не влияет на исполнение, разве что на скорость исполнения

MasterZivЕсли всё сделать так, как я говорю, то setForwardOnly(true); ставить не нужно,
оно и так будет само.


Qt Assistent:
ODBC Stored Procedure Support

With Microsoft SQL Server the result set returned by a stored procedure that uses the return statement, or returns multiple result sets, will be accessible only if you set the query's forward only mode to forward using QSqlQuery::setForwardOnly().

Код: plaintext
1.
2.
3.
4.
5.
// STORED_PROC uses the return statement or returns multiple result sets
 QSqlQuery query;
 query.setForwardOnly(true);
 query.exec("{call STORED_PROC}");
>      mainQuery->exec();


собственно пробовал и без setForwardOnly(true)...
MasterZivПроверь, может ты неверный вызов испльзульешь.

я тоже предполагаю что косяк в чём то элементарном ;)
не может же быть такого
тему завёл уже отчаявшись - ни одного писка в тырнете :)
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702299
fte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
см. хелп по QSqlQuery

Binding values to a stored procedure:

This code calls a stored procedure called AsciiToInt(), passing it a character through its in parameter, and taking its result in the out parameter.

Код: plaintext
1.
2.
3.
4.
5.
6.
     QSqlQuery query;
     query.prepare("CALL AsciiToInt(?, ?)");
     query.bindValue(0, "A");
     query.bindValue(1, 0, QSql::Out);
     query.exec();
     int i = query.boundValue(1).toInt(); // i is 65


Note that unbound parameters will retain their values.

Stored procedures that uses the return statement to return values, or return multiple result sets, are not fully supported. For specific details see SQL Database Drivers.
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702320
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fteсм. хелп по QSqlQuery
...

ну так и что я пропустил то? :)
в этом примере идёт речь о возврате параметра из ХП
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702546
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> всё это я пробовал...
> результат одинаковый
>

Это не надо пробовать, это надо так делать.
Оно может и не влиять на желаемый тобой результат,
но так надо делать по уму. Просто потому что надо.


> With Microsoft SQL Server the result set returned by a stored procedure that
> uses the return statement, or returns multiple result sets, will be accessible
> only if you set the query's forward only mode to forward using
> QSqlQuery::setForwardOnly().

Ну ладно, оставь.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702576
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЭто не надо пробовать, это надо так делать.
Оно может и не влиять на желаемый тобой результат,
но так надо делать по уму. Просто потому что надо.

скажем так - изначально так и было ;)
через call
я знаю что "надо так" ;)

Для подтверждения заменил:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
    QString sqlString;
    sqlString = "{CALL teststorproc (?)}";
    mainQuery->prepare(sqlString);
    mainQuery->bindValue(0,"2");

    mainQuery->setForwardOnly(true);
    mainQuery->exec();



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE PROCEDURE [dbo].[teststorproc]
@param varchar(10)
AS
BEGIN
--	SET NOCOUNT ON

--if 3=3
select * from SomeTable
where field2 like('%'+ltrim(rtrim(@param))+'%')
END



пока не раскоменнтишь любую из строк всё работает...
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702703
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>
> CREATE PROCEDURE [dbo].[teststorproc]
> @paramvarchar(10)
> AS
> BEGIN
> -- SET NOCOUNT ON
>
> --if 3=3
> select * from SomeTable
> where field2like('%'+ltrim(rtrim(@param))+'%')
> END

> пока не раскоменнтишь любую из строк всё работает...

Не может быть, чтобы в QT было всё так плохо...



SET NOCOUNT ON короче надо как-то поставить
в той же коннекции до выполнения запроса.

Можно через ODBC API включить его в коннекции (см. документацию на драйвер, по
идее должно поддерживаться), или просто перед этим запросом выполнить
языковой запрос
"SET NOCOUNT ON"

Если и так не будет работать, я уж и не знаю....
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702767
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНе может быть, чтобы в QT было всё так плохо...

как бы плохо только с MSSQL :)
точнее с QODBC
и то - по неподтверждённым другими пока данным
может кто-нибудь опровергнет всё же?

MasterZivSET NOCOUNT ON короче надо как-то поставить
в той же коннекции до выполнения запроса.
...
Если и так не будет работать, я уж и не знаю....


не срабатывает...
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37702843
fte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а на консоли приложения не выводится никакой диагностики?
сдаётся мне, что mainQuery->record() не может правильно сформировать.....

ИМХО:
если Ваша процедура с комментариями, то она трансформируется к виду
create procedure ....
as select ....
выходные параметры процедуры на автомате будут в системных таблицах прописаны, и поэтому вы видите результат,
а если так -
create procedure .....
begin
.....
select a,b,c
select f,d
.....
end
что возвратит Ваша процедура?
a,b,c
f,d,null

думаю
recordset(a,b,c)
recordset(f,d)

а вот это думаю драйвер ODBC не может понять.....
поэтому надо выходные параметры явно указать....
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37703014
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fteа на консоли приложения не выводится никакой диагностики?
сдаётся мне, что mainQuery->record() не может правильно сформировать.....
...
что возвратит Ваша процедура?
a,b,c
f,d,null

думаю
recordset(a,b,c)
recordset(f,d)

если честно - ни чего не понял :)
текст процедуры я выше приводил
fteпоэтому надо выходные параметры явно указать....
там результат запроса - таблица
ни каких выходных параметров нет
результат возвращается при отсутствии дополнительных управляющих конструкций
кстати, проверил на MSSQL2000 - результат идентичный
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37703165
fte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тогда может так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE FUNCTION [ owner_name. ] function_name 
    ( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] ) 

RETURNS TABLE 

[ WITH < function_option > [ [,] ...n ] ] 

[ AS ] 

RETURN [ ( ] select-stmt [ ) ] 



mainQuery->prepare("select * from dbo.myfunc(2)");
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37703289
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> CREATE FUNCTION [ owner_name. ] function_name
> ( [ { @parameter_name[AS] scalar_parameter_data_type[ =default ] } [ ,...n] ] )
>
> RETURNS TABLE

Не нужно это.
Это нужно, когда результат выполнения процедуры участвует в запросе вместо таблицы.

А чтобы получить данные на клиенте это ни на фиг не нужно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37703617
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
проверил QODBC в работе с ASA 8.02 с аналогичной процедурой - всё отлично отрабатывает...
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37709001
Фотография v6y
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chagoserg,
Если всё еще актуально:

В вашем случае

viewModel->lastError() == QSqlError(-1, " Forward-only queries cannot be used in a data model ", "")

Проблема с QSqlQueryModel, а не с драйвером
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37709303
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
v6y"Forward-only queries cannot be used in a data model"

Проблема с QSqlQueryModel, а не с драйвером

да, это уже я тоже обнаружил...
только непонятно, почему при отключении управляющих конструкций результат перестаёт быть forward-only
при этом setForwardOnly влияния не оказывает

и кроме того - с ASA 8.02 через QODBC в тоже время нет ни каких проблем хоть стоит forward-only хоть нет...

как я писал выше :
With Microsoft SQL Server the result set returned by a stored procedure that uses the return statement, or returns multiple result sets, will be accessible only if you set the query's forward only mode to forward using QSqlQuery::setForwardOnly().

ужасное противоречие, однако :)
чтобы получить результат ХП от MSSQL надо обязательно сделать setForwardOnly(), но стандартная QSqlQueryModel его не примет
что ж, выход один - своя модель...
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #37752483
chagoserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
снова подниму тему...

v6yПроблема с QSqlQueryModel, а не с драйвером
выход один - своя модель...

изготовление собственной модели не стало выходом - проблема осталась.
и дело совсем не в forward-only
MS SQL не возвращает результат, точнее numRowsAffected() равен -1 - "cannot be determined"

скорее всего проблема всё таки в QODBC
поскольку именно QODBC прослойка к основному ODBC и тот же Visual FoxPro не имеет проблем с получением результата от сервера не смотря на наличие или отсутствие управляющих конструкций.

кому интересно - прикладываю проект
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Qt и MSSQL 2005
    #38403517
Koschey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chagoserg,

Столкнулся с такой же проблемой. В хранимой процедуре нельзя ничего разместить кроме одного селекта.
Воспользовался советом Fte. Идея с функцией с инструкциями, возвращающая табличные данные. В коде пишу запрос на выборку данных, вместо таблицы указываю функцию. В свою очередь в функции можно расположить код, который мне необходим. Недостаток в том, что пока не знаю как воспользоваться sp_executesql и заставить функцию вернуть её результат.
Есть еще второй вариант, но я его еще не опробовал.
Это работа с методом QSqlQuery::nextResult(). Он рассчитан на запросы возвращающие несколько наборов данных. В нашем случае, очень похоже, что это и происходит, при включении в текст хранимой процедуры дополнительных команд.
...
Рейтинг: 0 / 0
Qt и MSSQL 2005
    #38403525
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chagoserg,

Проблема в том, что QT будет ожидать в таком случае набор данных, а посколько select под if, набор никогда не придет, и в соединении с бд возникнет ошибка состояния: клиент запрашивает открытие курсора, а курсора на сервере нет.

Эту проблему легко обойти, выдавая даже в случае else пустой набор данных такой, же структуры. При этом набор появится и клиентское приложение будет довольно.
...
Рейтинг: 0 / 0
25 сообщений из 35, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Qt и MSSQL 2005
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]