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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как запустить несколько предложений SQL в одном QSqlQuery.exec?  (Прочитано 6075 раз)
evgeniy
Гость
« : Ноябрь 21, 2011, 13:33 »

Например, мне нужно вставить строку и получить сразу сгенерённый id.
Если делать так (см. ниже), то не срабатывет, потому что открывется другая сессия и last_insert_rowid возвращает 0 (как и должен):
  query.exec("insert into KS (ts, Value) values (" + ts + ", '')");
  query.exec("select last_insert_rowid()");

Помогите! Непонимающий
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #1 : Ноябрь 21, 2011, 13:36 »

1. Неверный запрос. Должен выдавать ошибку.
2. Используй bool QSqlDatabase::transaction ()
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
evgeniy
Гость
« Ответ #2 : Ноябрь 21, 2011, 13:49 »

Я как раз про это и говорю: выдаёт ошибку, когда пихаешь в exec больше одного предложения SQL. Что с transaction, что без него - всё также. А в ошибке - пустой текст! Причём несмотря на ошибку, первое предложение выполняется (если не откатывать). Может это только в SQLite так?
« Последнее редактирование: Ноябрь 21, 2011, 14:07 от evgeniy » Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #3 : Ноябрь 21, 2011, 14:25 »

Что с transaction, что без него - всё также.
db.transaction();
query.exec("insert into KS (ts, Value) values (" + ts + ", '')");
query.exec("select last_insert_rowid()");
db.commit();

Кроме того вместо "select last_insert_rowid()" есть QSqlQuery::lastInsertId ().


Ну и лучше, конечно, использовать prepare+bind вместо сложения строк.
Записан
evgeniy
Гость
« Ответ #4 : Ноябрь 21, 2011, 15:13 »

Спасибо огромное!!!
Я сам мог бы догадаться, что в одной транзакции не откроются две разные сессии, но похоже большая часть умных мыслей у меня в свопинге.
Еще немaло пришлось повозиться, чтобы догадаться сделать query.first() перед взятием значения.
Кстати от bindoв я ушёл, потому что он начал на них ругаться, а возвращать их лень и некогда.
Вот так работает:
  db.transaction();
  query.exec("insert into KS (ts, Value) values (" + ts + ", '')")
  query.exec("select last_insert_rowid()")
  db.commit();
  query.first();
  int id = query.value(0).toInt();
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #5 : Ноябрь 21, 2011, 15:17 »

Если БД поддерживает, можно заюзать RETURNING у инсерта и все получится в одном запросе.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
evgeniy
Гость
« Ответ #6 : Ноябрь 21, 2011, 17:48 »

Это я знаю, спасибо!
Записан
Странник
Гость
« Ответ #7 : Ноябрь 22, 2011, 10:32 »

а если так, в одном пакете:
Код:
sqlQuery.exec("INSERT INTO t (f1, f2) VALUES (1, 2); SELECT last_insert_rowid()")
на SQLite не помню, работает ли. MS SQL хавает.
Записан
Prm
Гость
« Ответ #8 : Ноябрь 24, 2011, 09:26 »

Можно еще хранимую процедуру написать и вызывать ее в одну строку :-)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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