在 while 循环中选择并更新 sqlite 数据库

在 while 循环中选择并更新 sqlite 数据库

有一个 bash 脚本可以对引用 sqlite 数据库的文件执行“一些魔法”™,执行完“一些魔法”™后,数据库应该会更新。以下是简化的代码

sqlite3 database.db "select NUMBER from table WHERE STATUS = 'N'" | while read line; do
    SELECTION=$(echo $line | awk -F'|' '{ print $1 }')
    [some magic]™
    sqlite3 database.db "update table SET STATUS='Y' WHERE NUMBER='$SELECTION'"
done

一切正常,sqlite 数据库将被逐行读取,我可以对引用的文件执行“一些魔术”™,但我无法更新数据库中的行 - 我收到一个错误:

错误:数据库已被锁定

有人知道我如何在读取数据库的同时更新数据库吗?或者还有其他解决方案吗?

答案1

如果您不想转移到真正的 SQL 数据库,并且无法临时存储结果,则必须确保不要在同一个表上运行并发 SELECT 和 UPDATE。

限制SELECT 指令。

因此你可以这样做:

line=x
while [ -n "$line" ]
do
    line=$(sqlite3 database.db "select NUMBER from table WHERE STATUS = 'N'" LIMIT 1)
    SELECTION=$(echo $line | awk -F'|' '{ print $1 }')
    [some magic]™
    sqlite3 database.db "update table SET STATUS='Y' WHERE NUMBER='$SELECTION'"
done

这将使 SELECT 始终只返回一个结果并完成,然后您将处理和更新该结果,并重新运行 SELECT 以获取下一个结果(由于 STATUS 发生变化,SELECT 将获取下一个值,而不是旧值,因为它不再匹配“N”)

或者您可以通过 SQL 而不是 shell 来做“一些魔术(tm)”,这样您就可以将所有工作转移到 SQL 引擎......

答案2

您必须分两步进行。要么将第一个查询的结果存储到临时文件(或变量)中,然后处理它;要么将更新语句累积在临时文件或变量中,并在选择完成后执行。

相关内容