Russian Qt Forum
Декабрь 17, 2017, 07:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Выполнение встроенных процедур MS SQL Server  (Прочитано 2387 раз)
vladimirse
Новичок

Offline Offline

Сообщений: 18



Просмотр профиля
« : Март 10, 2017, 11:39 »

Доброго времени суток, уважаемые!
Есть необходимость обратиться к БД по средством встроенной процедуры, увы другие варианты не возможны.
СУБД MS SQL. В ms sql management studio процедура выглядит следующим образом (с примером вводимых параметров):
Код
SQL
USE [OIK]
GO
 
DECLARE @return_value int
EXEC @return_value = [dbo].[Step]
           @Cat = N'I',
           @Ids = N'30568',
           @Start = N'2017-03-01 11:00:00.000',
           @Stop = N'2017-03-01 14:30:00.000',
           @Step = 60
 
SELECT 'Return Value' = @return_value
 
GO
 

Не могу догнать как ее выполнить в QT. Пытаюсь следующим образом:
Код
C++ (Qt)
...
if (db.open())
   {
       QString q;
       QSqlQuery query(db);
       q.sprintf("CALL dbo.Step(%s, %s, %s, %s, %d)", "S", "11", "2017-03-01 11:00:00.000", "2017-03-05 00:00:00.000", 60);
       qDebug() << query.exec(q);
}
 

Соответственно получаю "false".
Подскажите пожалуйста как это правильно реализовать.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5634


Жаждущий знаний


Просмотр профиля
« Ответ #1 : Март 10, 2017, 11:55 »

Никогда так не делай. Используй QSqlQuery::addBindValue.

Код
C++ (Qt)
query.prepare("Call dbo.Step(?, ?, ?, ?, ?)");
query.addBindValue("S");
....
query.exec();
 
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
-------------------------------
https://twitter.com/panter_dsd
https://facebook.com/panter.dsd
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5634


Жаждущий знаний


Просмотр профиля
« Ответ #2 : Март 10, 2017, 11:57 »

По поводу самого sql ничего не могу сказать, не вызывал хранимки в мускуле. В постгресе я бы сделал: "SELECT procedure_name(?, ?, ?, ?, ?)"
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
-------------------------------
https://twitter.com/panter_dsd
https://facebook.com/panter.dsd
vladimirse
Новичок

Offline Offline

Сообщений: 18



Просмотр профиля
« Ответ #3 : Март 10, 2017, 12:07 »

Никогда так не делай. Используй QSqlQuery::addBindValue.

Код
C++ (Qt)
query.prepare("Call dbo.Step(?, ?, ?, ?, ?)");
query.addBindValue("S");
....
query.exec();
 

Большое спасибо, исправил!
Код
C++ (Qt)
QSqlQuery query(db);
query.prepare("CALL dbo.Step ( ?, ?, ?, ?, ? )");
query.addBindValue("S");
query.addBindValue("11");
query.addBindValue("2017-03-01 11:00:00.000");
query.addBindValue("2017-03-05 00:00:00.000");
query.addBindValue(60);
qDebug() << query.exec();
 
Но пока, увы, не работает. :-(
« Последнее редактирование: Март 10, 2017, 12:09 от vladimirse » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5634


Жаждущий знаний


Просмотр профиля
« Ответ #4 : Март 10, 2017, 12:09 »

Код
C++ (Qt)
qDebug () << query.lastErro().text()
 
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
-------------------------------
https://twitter.com/panter_dsd
https://facebook.com/panter.dsd
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5634


Жаждущий знаний


Просмотр профиля
« Ответ #5 : Март 10, 2017, 12:09 »

Дату/Время передавай не строкой, а при помощи QDateTime. addBindValue понимает типы и корректно их передает в БД.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
-------------------------------
https://twitter.com/panter_dsd
https://facebook.com/panter.dsd
vladimirse
Новичок

Offline Offline

Сообщений: 18



Просмотр профиля
« Ответ #6 : Март 10, 2017, 15:23 »

Дату/Время передавай не строкой, а при помощи QDateTime. addBindValue понимает типы и корректно их передает в БД.

Тут все таки проблема видимо в другом, нашел процедуру без параметров, выполняю:
Код
C++ (Qt)
QSqlQuery query(db);
query.exec("call [dbo].[GetCurrentDate_ForKU]"); // пробовал различные варианты записи
qDebug () << query.lastError().text();
 


Выдает:
Код:
QTDS: General SQL Server error: Check messages from the SQL Server
В логах на сервере пусто.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5634


Жаждущий знаний


Просмотр профиля
« Ответ #7 : Март 10, 2017, 15:32 »

1. Простые запросы работают?
2. В консоли mysql запрос "call [dbo].[GetCurrentDate_ForKU]" срабатывает?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
-------------------------------
https://twitter.com/panter_dsd
https://facebook.com/panter.dsd
vladimirse
Новичок

Offline Offline

Сообщений: 18



Просмотр профиля
« Ответ #8 : Март 10, 2017, 15:47 »

1. Простые запросы работают?
2. В консоли mysql запрос "call [dbo].[GetCurrentDate_ForKU]" срабатывает?

Разобрался. Работает вот так:
Код
C++ (Qt)
QSqlQuery query(db);
query.setForwardOnly(true);
query.prepare("exec [dbo].[Step] ?, ?, ?, ? ,?");
query.addBindValue("B");
query.addBindValue("11");
query.addBindValue("2017-03-01 11:00:00.000");
query.addBindValue("2017-03-05 00:00:00.000");
query.addBindValue("60");
query.exec();
 

Большое спасибо за помощь!
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5634


Жаждущий знаний


Просмотр профиля
« Ответ #9 : Март 10, 2017, 15:58 »

1. Какой-то очень странный синтаксис. Уверен, что нельзя как-то типа "SELECT Step(?, ?, ?, ?, ?)"?
2. Не используй строки, используй типы - это очень важно.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
-------------------------------
https://twitter.com/panter_dsd
https://facebook.com/panter.dsd
titan83
Самовар
**
Offline Offline

Сообщений: 197


Просмотр профиля
« Ответ #10 : Март 12, 2017, 14:35 »

Извините, не удержался))
"Не используй строки Люк, используй типы - это путь силы." (с) Мастер Йода.
А вообще мне лично так нравится больше:
Код:
    for (int i = 0; i < queryParameters.size(); i++)
        lQueryText.replace(queryParameters.keys().at(i), queryParameters.value(queryParameters.keys().at(i)));
где
lQueryText - QString
queryParameters - QHash<QString, QString>
И душевно работает без QSqlQuery::prepare
И строки использовать намного удобнее, чем over9000 типов, все становится единообразно. Хотя, если оплата за количество строк кода, то смысл есть))
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3846



Просмотр профиля
« Ответ #11 : Март 12, 2017, 15:42 »

А вообще мне лично так нравится больше:
Только это ужасно не эффективно.
Вы для функции replace дважды вызываете queryParameters.keys(), который формирует список ключей пробегаясь по всей коллекции и заполняя список. И так для каждого запроса.
Записан
titan83
Самовар
**
Offline Offline

Сообщений: 197


Просмотр профиля
« Ответ #12 : Март 12, 2017, 17:03 »

А вообще мне лично так нравится больше:
Только это ужасно не эффективно.
Вы для функции replace дважды вызываете queryParameters.keys(), который формирует список ключей пробегаясь по всей коллекции и заполняя список. И так для каждого запроса.
Что поделать... Все высокоуровневое программирование ужасно неэффективно, по сравнению с ассемблером (я сравнилал бейсик и асм на z80).
Но мне важнее написать две строки кода, а не десять, даже в ущерб эффективности.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3846



Просмотр профиля
« Ответ #13 : Март 12, 2017, 17:20 »

Что поделать... Все высокоуровневое программирование ужасно неэффективно, по сравнению с ассемблером (я сравнилал бейсик и асм на z80).
Ну если сравнивать бейсик и ассемблер, то да. А так нет. Улыбающийся

Но мне важнее написать две строки кода, а не десять, даже в ущерб эффективности.
Напрасно. Это можно написать в три строки (вместо двух) без ущерба для эффективности.
Записан
titan83
Самовар
**
Offline Offline

Сообщений: 197


Просмотр профиля
« Ответ #14 : Март 12, 2017, 18:25 »

Что поделать... Все высокоуровневое программирование ужасно неэффективно, по сравнению с ассемблером (я сравнилал бейсик и асм на z80).
Ну если сравнивать бейсик и ассемблер, то да. А так нет. Улыбающийся

Но мне важнее написать две строки кода, а не десять, даже в ущерб эффективности.
Напрасно. Это можно написать в три строки (вместо двух) без ущерба для эффективности.
Вероятно, лет через 15 я с вами соглашусь Подмигивающий а пока мне это видится нерациональной операцией (больше 4(!) параметров в запросы я пока не передаю).
Автор, извини за флуд, Old, предлагаю закрыть этот небольшой офф.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  

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