Russian Qt Forum
Ноябрь 24, 2024, 05:37 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QODBC + MSSQL пустые строки в возвращаемых параметрах?  (Прочитано 13922 раз)
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 процедура выполняется и параметры отправляются клиенту.

Что не так, помогите!
Записан
spectre71
Гость
« Ответ #1 : Июнь 10, 2009, 12:29 »

QSqlQuery::next () Непонимающий
Записан
mik1133
Гость
« Ответ #2 : Июнь 10, 2009, 12:37 »

QSqlQuery::next () Непонимающий
Гм... вопрос не очень понятен.
Если речь идет о применении query.next(), то скажу следующее: хранимая процедура не вовращает больше никаких данных, только через параметры, поэтому вызов query.next() вернет false.
Записан
spectre71
Гость
« Ответ #3 : Июнь 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()).

« Последнее редактирование: Июнь 10, 2009, 12:42 от spectre71 » Записан
mik1133
Гость
« Ответ #4 : Июнь 10, 2009, 12:48 »

Разве можно с помощью query.exec("...") вызвать хранимую процедуру (stored procedure? Если можно, то как тогда передать хранимой процедуре параметры?
Записан
spectre71
Гость
« Ответ #5 : Июнь 10, 2009, 12:58 »

Ты вызываешь exec();
Просто без параметров!
В документацию заглядывал?
Любой запрос возвращает таблицу.
И сначала необходимо установить позицию ("Курсор") на запись, а потом уже пытаться считывать данные из записи
Записан
spectre71
Гость
« Ответ #6 : Июнь 10, 2009, 13:04 »

Хотя может я и не прав с exec()
Записан
mik1133
Гость
« Ответ #7 : Июнь 10, 2009, 13:07 »

Ты вызываешь exec();
Просто без параметров!
В документацию заглядывал?
Любой запрос возвращает таблицу.
И сначала необходимо установить позицию ("Курсор") на запись, а потом уже пытаться считывать данные из записи
exec() я и вызываю без параметров. Я пример для этого специально привел (в пример заглядывал? Подмигивающий)
понятно, что таблицу, но почему тогда в первый параметр Param2 типа qlonglong я получаю значение от БД (значение 123), а в параметрах типа QString я получаю пустые строки?
Причем здесь курсор?  И как его установить на запись?
Записан
Rcus
Гость
« Ответ #8 : Июнь 10, 2009, 13:08 »

А что возвращает QSqlQuery::boundValues()? кстати не могу не заметить подозрительность конструкции (QString)""
Записан
mik1133
Гость
« Ответ #9 : Июнь 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();

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

   
Записан
spectre71
Гость
« Ответ #10 : Июнь 10, 2009, 13:36 »

Попробуй сделать StrP1 - INT и посмотри вернет ли 123.
Если нет - скорее что-то криво в процедуре
Записан
mik1133
Гость
« Ответ #11 : Июнь 10, 2009, 13:48 »

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

Пойду на сайт производителей Qt - их буду вопросами мучить. Всем спасибо! Улыбающийся
Записан
spectre71
Гость
« Ответ #12 : Июнь 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()
   }
 

И посмотри сколько и чего ты получаешь
Записан
roman.ks
Гость
« Ответ #13 : Июнь 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

Может быть это поможет
Записан
EhTemka
Гость
« Ответ #14 : Июнь 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().
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.093 секунд. Запросов: 21.