Russian Qt Forum

Qt => Базы данных => Тема начата: evgeniy от Ноябрь 21, 2011, 13:33



Название: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: 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()");

Помогите! ???


Название: Re: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: Пантер от Ноябрь 21, 2011, 13:36
1. Неверный запрос. Должен выдавать ошибку.
2. Используй bool QSqlDatabase::transaction ()


Название: Re: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: evgeniy от Ноябрь 21, 2011, 13:49
Я как раз про это и говорю: выдаёт ошибку, когда пихаешь в exec больше одного предложения SQL. Что с transaction, что без него - всё также. А в ошибке - пустой текст! Причём несмотря на ошибку, первое предложение выполняется (если не откатывать). Может это только в SQLite так?


Название: Re: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: LisandreL от Ноябрь 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 вместо сложения строк.


Название: Re: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: evgeniy от Ноябрь 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();


Название: Re: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: Пантер от Ноябрь 21, 2011, 15:17
Если БД поддерживает, можно заюзать RETURNING у инсерта и все получится в одном запросе.


Название: Re: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: evgeniy от Ноябрь 21, 2011, 17:48
Это я знаю, спасибо!


Название: Re: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: Странник от Ноябрь 22, 2011, 10:32
а если так, в одном пакете:
Код:
sqlQuery.exec("INSERT INTO t (f1, f2) VALUES (1, 2); SELECT last_insert_rowid()")
на SQLite не помню, работает ли. MS SQL хавает.


Название: Re: Как запустить несколько предложений SQL в одном QSqlQuery.exec?
Отправлено: Prm от Ноябрь 24, 2011, 09:26
Можно еще хранимую процедуру написать и вызывать ее в одну строку :-)