Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 预测下一个自动插入的行id(SQLite)_Database_Sqlite - Fatal编程技术网

Database 预测下一个自动插入的行id(SQLite)

Database 预测下一个自动插入的行id(SQLite),database,sqlite,Database,Sqlite,我试图在插入下一行之前找到(使用)下一行ID的可靠方法。我需要为另一个insert语句使用id,但不能立即插入并获取下一行 预测下一个id是否与获取最后一个id并添加一个id一样简单?这是保证吗 编辑:多一点道理。。。 我无法立即插入,因为用户可能会取消插入。用户将进行一些更改,SQL语句将被存储,用户可以从中保存(一次插入所有行)或取消(不更改任何内容)。在程序崩溃的情况下,所需的功能是什么都不会改变。我认为这是无法做到的,因为无法确保在您请求和插入之间不会插入任何内容。(您可能可以将表锁定为

我试图在插入下一行之前找到(使用)下一行ID的可靠方法。我需要为另一个insert语句使用id,但不能立即插入并获取下一行

预测下一个id是否与获取最后一个id并添加一个id一样简单?这是保证吗

编辑:多一点道理。。。
我无法立即插入,因为用户可能会取消插入。用户将进行一些更改,SQL语句将被存储,用户可以从中保存(一次插入所有行)或取消(不更改任何内容)。在程序崩溃的情况下,所需的功能是什么都不会改变。

我认为这是无法做到的,因为无法确保在您请求和插入之间不会插入任何内容。(您可能可以将表锁定为插入,但很恶心)


顺便说一句,我只使用了MySQL,但我不认为这会有任何区别)

最有可能的情况是,您应该能够+1最新的id。我将查看排序表中现有的所有id。。它们是否一致?每行的ID是否比最后一行多一个?如果是这样,你可能会没事的。不过,我会在代码中留下注释来解释这个假设。执行锁定将有助于确保在执行此操作时不会获得额外的行。

选择最后一个\u insert\u rowid()值。

在某些条件下,例如,使用相同的数据库连接,并且没有其他并发写入程序,您可以在返回的值中添加1。当然,您可以参考sqlite源代码来支持这些假设


但是,你也可以认真考虑使用不同的方法,不需要预测下一个ID。即使你对你使用的SQLite版本正确,将来的事情也会改变,它肯定会使移动到一个不同的数据库更加困难。

< P>插入一个带有无效标记的行,获取ID,根据需要进行编辑,必要时删除或标记为有效。那就不用担心序列中的间隙了

顺便说一句,你需要弄清楚如何自己做无效的部分。根据具体情况,将某些内容标记为NULL可能会起作用


编辑:如果可以,请使用Eevee关于使用适当事务的建议。这项工作要少得多。

一次取消或提交一系列数据库操作正是事务的目的。查询
开始在用户开始摆弄和
提交之前一旦他/她完成。您可以保证应用所有更改(如果您提交)或放弃所有更改(如果您查询
回滚;
,如果程序崩溃、断电等)。一旦从数据库中读取数据,您还可以保证数据在事务结束之前是良好的,因此您可以获取
MAX(id)
或任何您想要的内容,而不必担心竞争条件


本主题中需要说的大部分内容都已经但是,在进行此操作时,请非常小心比赛条件。如果两个人都打开你的应用程序/网页/任何东西,其中一人添加了一行,另一个用户将尝试插入一个具有相同ID的行,你将遇到很多问题。

我意识到使用SQLite的应用程序很小,SQLite有自己的语义。在这里发布的其他解决方案可能会在这个特定环境中产生您想要的效果,但在我看来,到目前为止我读到的每一个解决方案都是根本不正确的,应该避免使用

在正常环境中,应不惜一切代价避免为用户输入而持有事务。如果您需要存储中间数据,那么处理此问题的方法是为此将信息写入临时表,然后尝试在原子事务中写入所有信息。在多用户环境中,保留事务会导致死锁和并发噩梦

在大多数环境中,您不能假定通过事务中的SELECT检索的数据是可重复的。比如说

SELECT Balance FROM Bank ...
UPDATE Bank SET Balance = valuefromselect + 1.00 WHERE ...
更新后的余额很可能会发生变化。有时,您可以通过在事务中首先更新您感兴趣的银行行来解决此问题,因为这样可以确保锁定该行,防止在事务完成之前进一步更新更改其值

但是,在这种情况下,有时确保一致性的更好方法是在update的WHERE子句中检查您对数据内容的假设,并在应用程序中检查行数。在上面的示例中,当您“更新银行”时,WHERE子句应提供余额的预期现值:

WHERE Balance = valuefromselect
如果预期余额不再匹配,WHERE条件也不匹配--UPDATE不执行任何操作,rowcount返回0。这告诉您存在并发问题,当其他人不试图同时更改您的数据时,您需要再次运行该操作

select max(id) from particular_table;

下一个id将是最大id的+1。

尝试
SELECT*from SQLITE_SEQUENCE,其中name='TABLE'。这将包含一个名为
seq
的字段,它是所选表格的最大数字。将1添加到此值以获取下一个ID

另请参见,这是上述信息的来源

干杯

select max(id) from particular_table is unreliable for the reason below..

“上述普通ROWID选择算法将生成单调递增的唯一ROWID,只要您从未使用最大ROWID值,也从未删除表中具有最大ROWID的条目。如果删除了行或创建了具有最大可能ROWID的行,则在创建新行时可能会重用以前删除的行中的ROWID,并且新创建的ROWID可能不是严格的升序或升序