Представьте, что у меня есть следующее определение таблицы SQLite:
create table test (id integer primary key, info integer);
и следующие записи:
id | info
----------
1 | 10
2 | 20
3 | 30
Я хочу использовать Qt’s QSqlQuery
класс для того, чтобы prepare()
запрос и использовать bindValue()
функция.
То, что я пытаюсь достичь, это нечто вроде
insert into test values (
( select id from test where ROWID = last_insert_rowid() )+100,
666
);
чтобы получить:
id | info
----------
1 | 10
2 | 20
3 | 30
103 | 666
Хотя это работает напрямую exec()
в заявлении через QSqlQuery qry
объект, это
//qry is set up correctly.
qry.prepare("insert into test values (?,?);");
qry.bindValue(0, "select id from test where ROWID = last_insert_rowid() )+100");
qry.bindValue(1,666);
qry.exec();
не работает (несоответствие типа данных).
1) Как я могу заставить это работать с помощью bindValue()
?
2) Какой самый лучший способ добиться того же поведения без использования last_insert_rowid()
?
3) Какое значение будет возвращено приведенным выше кодом для id
если в таблице до сих пор не было строк? Нуль?
1) Вы не можете связать выражение SQL с «?», Это является целью привязки Просто забудь о первом «?» и связать только одно значение:
qry.prepare("insert into test values ( (select id from test where ROWID = last_insert_rowid() )+?,?);");
qry.bindValue(0,100);
qry.bindValue(0,666);
qry.exec();
2) Если у вас есть целочисленный столбец первичного ключа, sqlite last_insert_rowid()
вернет значение этого столбца, так что вы можете просто написать:
qry.prepare("insert into test values (last_insert_rowid()+?,?);");
qry.bindValue(0,100);
qry.bindValue(0,666);
qry.exec();
Думая о вашем предполагаемом поведении, это не будет вести себя как автоинкремент, потому что кто-то может вставить значение по индексу, которое вызовет конфликт для вашей следующей вставки. Более пуленепробиваемый подход заключается в увеличении максимального значения:
qry.prepare("insert into test values ( (select id from test order by id desc limit 1)+?,?);");
qry.bindValue(0,100);
qry.bindValue(0,666);
qry.exec();
3) Если таблица пуста, это select
вернусь null
, а также null+100
все еще null
, и это вызовет автоматическое увеличение, так что 1 вставляется.
Других решений пока нет …