在 bindValue(...) 函数中使用 select 语句 - Qt & SQLite

Using a select statement in the bindValue(...) function - Qt & SQLite

本文关键字:语句 select Qt SQLite bindValue 函数      更新时间:2023-10-16

假设我有以下SQLite表定义:

create table test (id integer primary key, info integer);

以及以下条目:

id  | info
----------
1   | 10
2   | 20
3   | 30

我想使用Qt的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

虽然它通过QSqlQuery qry对象直接对语句进行exec()操作,但这个

//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) 如果您有integer主键列,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。