Russian Qt Forum

Qt => Базы данных => Тема начата: mik1133 от Июнь 10, 2009, 12:02



Название: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: mik1133 от Июнь 10, 2009, 12:02
Всем привет!
Использую  Qt v4.5.1. Через драйвер QODBC обращаюсь к БД MS SQL Server, вызываю хранимую процедуру. Хранимая процедура возвращает значения через параметры. Если парметр типа QString (NVARCHAR для MSSQL) то всегда возвращается пустая строка. Вот пример кода:

   . . .

   query.prepare("exec TestProcedure ?, ?, ?, ?");

   query.bindValue("Param1", (qlonglong)0);
   query.bindValue("Param2", (qlonglong)0, QSql::InOut);
   query.bindValue("StrP1", (QString)"", QSql::InOut);
   query.bindValue("StrP2", (QString)"", QSql::InOut);

   query.exec();

   qlonglong Param2= query.boundValue("Param2").toLongLong();   // Param2 = 123
   QString StrP1= query.boundValue("StrP1").toString();         // StrP1 = "" ??? А должно быть "123"
   QString StrP2= query.boundValue("StrP2").toString();         // StrP2 = "" ??? А должно быть "test"

   . . .

По логам сервера MS SQL процедура выполняется и параметры отправляются клиенту.

Что не так, помогите!


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: spectre71 от Июнь 10, 2009, 12:29
QSqlQuery::next () ???


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: mik1133 от Июнь 10, 2009, 12:37
QSqlQuery::next () ???
Гм... вопрос не очень понятен.
Если речь идет о применении query.next(), то скажу следующее: хранимая процедура не вовращает больше никаких данных, только через параметры, поэтому вызов query.next() вернет false.


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: spectre71 от Июнь 10, 2009, 12:39
QSqlQuery::next () ???
Гм... вопрос не очень понятен.
Если речь идет о применении query.next(), то скажу следующее: хранимая процедура не вовращает больше никаких данных, только через параметры, поэтому вызов query.next() вернет false.
Запрос всегда возвращает таблицу.

bool QSqlQuery::exec ( const QString & query )
Цитировать
After the query is executed, the query is positioned on an invalid record and must be navigated to a valid record before data values can be retrieved (for example, using next()).



Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: mik1133 от Июнь 10, 2009, 12:48
Разве можно с помощью query.exec("...") вызвать хранимую процедуру (stored procedure? Если можно, то как тогда передать хранимой процедуре параметры?


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: spectre71 от Июнь 10, 2009, 12:58
Ты вызываешь exec();
Просто без параметров!
В документацию заглядывал?
Любой запрос возвращает таблицу.
И сначала необходимо установить позицию ("Курсор") на запись, а потом уже пытаться считывать данные из записи


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: spectre71 от Июнь 10, 2009, 13:04
Хотя может я и не прав с exec()


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: mik1133 от Июнь 10, 2009, 13:07
Ты вызываешь exec();
Просто без параметров!
В документацию заглядывал?
Любой запрос возвращает таблицу.
И сначала необходимо установить позицию ("Курсор") на запись, а потом уже пытаться считывать данные из записи
exec() я и вызываю без параметров. Я пример для этого специально привел (в пример заглядывал? ;))
понятно, что таблицу, но почему тогда в первый параметр Param2 типа qlonglong я получаю значение от БД (значение 123), а в параметрах типа QString я получаю пустые строки?
Причем здесь курсор?  И как его установить на запись?


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: Rcus от Июнь 10, 2009, 13:08
А что возвращает QSqlQuery::boundValues()? кстати не могу не заметить подозрительность конструкции (QString)""


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: mik1133 от Июнь 10, 2009, 13:31
А что возвращает QSqlQuery::boundValues()? кстати не могу не заметить подозрительность конструкции (QString)""
Про "подозрительность" согласен. Однако, если применить такую запись:

   query.bindValue("StrP1", "", QSql::InOut);
   query.bindValue("StrP2", "", QSql::InOut);

   query.exec();

а потом проверить тип возвращаемого параметра то получим следующее

   cout << "StrP1 type: " << query.boundValue("StrP1").typeName() << endl; // StrP1 type: QString

вот так. А далее код:

   QString StrP1 = query.boundValue("StrP1 ").toString();

возвращает пустую строку типа "".

   


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: spectre71 от Июнь 10, 2009, 13:36
Попробуй сделать StrP1 - INT и посмотри вернет ли 123.
Если нет - скорее что-то криво в процедуре


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: mik1133 от Июнь 10, 2009, 13:48
Попробуй сделать StrP1 - INT и посмотри вернет ли 123.
Если нет - скорее что-то криво в процедуре
Думаю дело не в процедуре. Дело в том, что я обращаюсь к той же самой процедуре на том же самом сервере, но через библиотеки сторонних разработчиков SQLAPI++, и все работает! Видимо это баг для Qt.
А еще пробовал применить Qt v 4.4.3 - то же самое. Возвращаются пустые строки. Но сервер то их отправляет! А данные теряются. Значит теряются в драйвере.

Пойду на сайт производителей Qt - их буду вопросами мучить. Всем спасибо! :)


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: spectre71 от Июнь 10, 2009, 14:01
Ты вообще попробовал?
И прежде чем чего-то куда-то писать поробуй еще вывести получаемые данные через:
QMap<QString, QVariant> boundValues () const

Код
C++ (Qt)
    QList<QVariant> list = query.boundValues().values();
    for (int i = 0; i < list.size(); ++i) {
        list.at(i).toString()
   }
 

И посмотри сколько и чего ты получаешь


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: roman.ks от Июнь 11, 2009, 10:42
Я не знаю как это работает в QODBC или QTDS. Мы у себя работает с QADO ( мост для ado, работает быстрее и больше драйверов, но только под винду ).
Так вот в ado ( не ado.net ) output параметры , будут раскручиваться в такую конструкцию ( проверяется профайлером ):

exec pr_proc1 @param1 output    раскручивается в


DECLARE @temp bla-bla
EXEC pr_proc1 @param1 = @temp output
SELECT @temp

Может быть это поможет


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: EhTemka от Июнь 11, 2009, 16:00
Писал как-то давно обращения к SQL Server процедурам. Сейчас посмотрел в код там так написано

Код
C++ (Qt)
 
       QSqlQuery query;
 
       query.setForwardOnly(true);
 
       query.prepare(queryText);
 
       if (query.exec())
       {
             bool isRecord = query.first();  
 
              if (isRecord)
              {
                      // беру данные
              }
       }
 
 

Обрати внимание на setForwardOnly(true) (помню зачем-то специально это писал, возможно дело связанно с одбс) и на first().


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: break от Июнь 16, 2009, 01:47
Вдруг чем то поможет

При написании ХП на Firebird для того чтобы хранимая процедура вернула набор данных надо использовать оператор SUSPEND; Не знаю нужен ли что-то подобное в MySQL.

чтобы вызвать хранимую процедуру через query

Код
C++ (Qt)
QSqlQuery query;
query.prepare( "select FIELD_1, FIELD_2 from SP_STORED_PROC( :PARAM_1, :PARAM_2 ) " );
query.bindValue( ":PARAM_1", 666 );
query.bindValue( ":PARAM_2", 999 );
query.exec();
 
query.first(); //
 
QSqlRecord rec = query.record();
 
qDebug() << query.value( rec.indexOf("FIELD_1") );
qDebug() << query.value( rec.indexOf("FIELD_2") );

мы всегда можем написать ХП чтобы она возвращала хотя бы 1 запись, но можно и проверять что после first набор установлен на валидную запись

Я такое использую - у меня работает


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: rusvid от Сентябрь 08, 2009, 05:01
Использую  Qt v4.5.1. Через драйвер QODBC обращаюсь к БД MS SQL Server, вызываю хранимую процедуру. Хранимая процедура возвращает значения через параметры. Если парметр типа QString (NVARCHAR для MSSQL) то всегда возвращается пустая строка.

Аналогичная проблема, удалось найти решение ?
вызов процедуры у меня происходит через CALL, но результат тот же самый - для строковых параметров возвращается пустая строка
Код:
    QSqlQuery query;
    query.setForwardOnly(true);
    query.prepare("{CALL fp_test(?,?,?)}");
    query.addBindValue(strName);
    query.addBindValue(strValue,QSql::Out);
    query.addBindValue(n,QSql::Out);
    if (!query.exec())
    {QMessageBox::information(0, QObject::tr("Error"), "Ошибка");
      return 1;
    }

    strValue = query.boundValue(1).toString();
    n = query.boundValue(2).toInt();;

    QMessageBox::information(0, QString().setNum(n), strValue);



Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: Vexator от Сентябрь 08, 2009, 05:52
А разве можно использовать exec() без first() или next() ? сколько работаю с qsql всегда их использую...


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: rusvid от Сентябрь 08, 2009, 06:07
А разве можно использовать exec() без first() или next() ? сколько работаю с qsql всегда их использую...
Вроде можно.
Смотри пример AsciiToInt на http://doc.trolltech.com/4.5/qsqlquery.html (http://doc.trolltech.com/4.5/qsqlquery.html)

Если хранимая процедура не возвращает результирующий набор, а только изменяет параметры,
то вполне логично, что нет необходимости в first() и next().


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: Vexator от Сентябрь 08, 2009, 06:30
Если хранимая процедура не возвращает результирующий набор, а только изменяет параметры,
то вполне логично, что нет необходимости в first() и next().
а да, забыл уточнить :)
имел виду операции чтения


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: mik1133 от Октябрь 08, 2009, 13:44
Снова всем привет!
Возвращаюсь к поднятой теме. На сайт разработчиков Qt было отправлено письмо об этой проблеме и вот наконец-то их ответ, цитирую:

. . .

Thankyou for your bug report, it has been entered into our system and will be available via http://bugreports.qt.nokia.com/browse/QTBUG-4634 when the new system goes live.

. . .

Thanks,
Bill
--
Bill King, Software Engineer
Qt Development Frameworks, Nokia Pty Ltd Brisbane Office


Будьте внимательны к новым продуктам  :), особенно к free software

Всем удачи!


Название: Re: QODBC + MSSQL пустые строки в возвращаемых параметрах?
Отправлено: rusvid от Октябрь 28, 2009, 06:37
В общем, решение было найдено.
Необходимо выделить место под возвращаемый параметр.
Т.е. если параметр "@Value varchar(50) out,"
делаем в программе strValue.reserve(51);

Полный пример:
Код:
    QString strName = "QSql::In string";
    QString strValue;
    strValue.reserve(51);
    int n = 0;

    QSqlQuery query;
    //query.setForwardOnly(true);
    query.prepare("{CALL fp_test(?,?,?)}");
    query.bindValue("Name",strName);
    query.bindValue("Value", strValue,QSql::Out);
    query.bindValue("Number",n,QSql::Out);
    if (!query.exec())
    { QMessageBox::information(0, QObject::tr("Error"), "Ошибка");
      return 1;
    }

    strName = query.boundValue("Name").toString();  // "QSql::In string"
    strValue = query.boundValue("Value").toString();  // "test"
    n = query.boundValue("Number").toInt();             // 123

P.S. Точнее необходимо резервировать место так, чтобы "влазил" фактический параметр, т.е.
в данном случае было достаточно strValue.reserve(5);
При strValue.reserve(4); вернулось бы "tes".