Название: Выполнение встроенных процедур MS SQL Server Отправлено: vladimirse от Март 10, 2017, 11:39 Доброго времени суток, уважаемые!
Есть необходимость обратиться к БД по средством встроенной процедуры, увы другие варианты не возможны. СУБД MS SQL. В ms sql management studio процедура выглядит следующим образом (с примером вводимых параметров): Код
Не могу догнать как ее выполнить в QT. Пытаюсь следующим образом: Код
Соответственно получаю "false". Подскажите пожалуйста как это правильно реализовать. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Пантер от Март 10, 2017, 11:55 Никогда так не делай. Используй QSqlQuery::addBindValue.
Код
Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Пантер от Март 10, 2017, 11:57 По поводу самого sql ничего не могу сказать, не вызывал хранимки в мускуле. В постгресе я бы сделал: "SELECT procedure_name(?, ?, ?, ?, ?)"
Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: vladimirse от Март 10, 2017, 12:07 Никогда так не делай. Используй QSqlQuery::addBindValue. Код
Большое спасибо, исправил! Код Но пока, увы, не работает. :-( Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Пантер от Март 10, 2017, 12:09 Код
Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Пантер от Март 10, 2017, 12:09 Дату/Время передавай не строкой, а при помощи QDateTime. addBindValue понимает типы и корректно их передает в БД.
Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: vladimirse от Март 10, 2017, 15:23 Дату/Время передавай не строкой, а при помощи QDateTime. addBindValue понимает типы и корректно их передает в БД. Тут все таки проблема видимо в другом, нашел процедуру без параметров, выполняю: Код
Выдает: Код: QTDS: General SQL Server error: Check messages from the SQL Server Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Пантер от Март 10, 2017, 15:32 1. Простые запросы работают?
2. В консоли mysql запрос "call [dbo].[GetCurrentDate_ForKU]" срабатывает? Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: vladimirse от Март 10, 2017, 15:47 1. Простые запросы работают? 2. В консоли mysql запрос "call [dbo].[GetCurrentDate_ForKU]" срабатывает? Разобрался. Работает вот так: Код
Большое спасибо за помощь! Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Пантер от Март 10, 2017, 15:58 1. Какой-то очень странный синтаксис. Уверен, что нельзя как-то типа "SELECT Step(?, ?, ?, ?, ?)"?
2. Не используй строки, используй типы - это очень важно. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: titan83 от Март 12, 2017, 14:35 Извините, не удержался))
"Не используй строки Люк, используй типы - это путь силы." (с) Мастер Йода. А вообще мне лично так нравится больше: Код: for (int i = 0; i < queryParameters.size(); i++) lQueryText - QString queryParameters - QHash<QString, QString> И душевно работает без QSqlQuery::prepare И строки использовать намного удобнее, чем over9000 типов, все становится единообразно. Хотя, если оплата за количество строк кода, то смысл есть)) Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Old от Март 12, 2017, 15:42 А вообще мне лично так нравится больше: Только это ужасно не эффективно.Вы для функции replace дважды вызываете queryParameters.keys(), который формирует список ключей пробегаясь по всей коллекции и заполняя список. И так для каждого запроса. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: titan83 от Март 12, 2017, 17:03 А вообще мне лично так нравится больше: Только это ужасно не эффективно.Вы для функции replace дважды вызываете queryParameters.keys(), который формирует список ключей пробегаясь по всей коллекции и заполняя список. И так для каждого запроса. Но мне важнее написать две строки кода, а не десять, даже в ущерб эффективности. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Old от Март 12, 2017, 17:20 Что поделать... Все высокоуровневое программирование ужасно неэффективно, по сравнению с ассемблером (я сравнилал бейсик и асм на z80). Ну если сравнивать бейсик и ассемблер, то да. А так нет. :)Но мне важнее написать две строки кода, а не десять, даже в ущерб эффективности. Напрасно. Это можно написать в три строки (вместо двух) без ущерба для эффективности. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: titan83 от Март 12, 2017, 18:25 Что поделать... Все высокоуровневое программирование ужасно неэффективно, по сравнению с ассемблером (я сравнилал бейсик и асм на z80). Ну если сравнивать бейсик и ассемблер, то да. А так нет. :)Но мне важнее написать две строки кода, а не десять, даже в ущерб эффективности. Напрасно. Это можно написать в три строки (вместо двух) без ущерба для эффективности. Автор, извини за флуд, Old, предлагаю закрыть этот небольшой офф. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Пантер от Март 13, 2017, 08:44 Извините, не удержался)) Это небезопасно и может привести к sql инъекции. Плюс, при использовании биндов не надо ничего экранировать."Не используй строки Люк, используй типы - это путь силы." (с) Мастер Йода. А вообще мне лично так нравится больше: Код: for (int i = 0; i < queryParameters.size(); i++) lQueryText - QString queryParameters - QHash<QString, QString> И душевно работает без QSqlQuery::prepare И строки использовать намного удобнее, чем over9000 типов, все становится единообразно. Хотя, если оплата за количество строк кода, то смысл есть)) Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: titan83 от Март 13, 2017, 12:30 Извините, не удержался)) Это небезопасно и может привести к sql инъекции. Плюс, при использовании биндов не надо ничего экранировать."Не используй строки Люк, используй типы - это путь силы." (с) Мастер Йода. А вообще мне лично так нравится больше: Код: for (int i = 0; i < queryParameters.size(); i++) lQueryText - QString queryParameters - QHash<QString, QString> И душевно работает без QSqlQuery::prepare И строки использовать намного удобнее, чем over9000 типов, все становится единообразно. Хотя, если оплата за количество строк кода, то смысл есть)) Про экранирование - спасибо, это существенная информация. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: Пантер от Март 13, 2017, 13:03 Код: query.exec(QString ("SELECT * FROM table_name WHERE id=%1").arg(idString)); Если в idString передать: "0; DROP TABLE table_name", то удалится таблица. Бинд это разрулит, ибо такая строка точно не закастится в тип id. Бинд работает на низком уровне, он не преобразуется в строку внутри Кьюта, а передается драйверу БД. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: titan83 от Март 13, 2017, 16:30 Код: query.exec(QString ("SELECT * FROM table_name WHERE id=%1").arg(idString)); Если в idString передать: "0; DROP TABLE table_name", то удалится таблица. Бинд это разрулит, ибо такая строка точно не закастится в тип id. Бинд работает на низком уровне, он не преобразуется в строку внутри Кьюта, а передается драйверу БД. Название: Re: Выполнение встроенных процедур MS SQL Server Отправлено: twp от Март 21, 2017, 16:41 Извините, не удержался)) Это небезопасно и может привести к sql инъекции. Плюс, при использовании биндов не надо ничего экранировать."Не используй строки Люк, используй типы - это путь силы." (с) Мастер Йода. А вообще мне лично так нравится больше: Код: for (int i = 0; i < queryParameters.size(); i++) lQueryText - QString queryParameters - QHash<QString, QString> И душевно работает без QSqlQuery::prepare И строки использовать намного удобнее, чем over9000 типов, все становится единообразно. Хотя, если оплата за количество строк кода, то смысл есть)) Есть еще вот что. СУБД кэширует и оптимизирует (прекомпилирует) все выполняемые запросы. Соответственно, когда в базу передается на выполнение один и тот же запрос, но с разными параметрами (указанными непосредственно в запросе), то база каждый раз будет интерпретировать такой запрос как новый, со своими издержками. Это не есть хорошо, особенно если в это время к базе поступают много запросов одновременно. Поэтому правильно передавать именно шаблон запроса через QSqlQuery::prepare. QSqlQuery::prepare как раз дает команду СУБД извлечь из кэша существующий или создать и оптимизировать новый запрос. Ну и уже потом в запрос передаются параметры через QSqlQuery::bindValue. Т.е. по сути такие запросы очень близки к хранимым процедурам. |