Aktualisieren Sie eine sqlite-Datenbank, während Sie in eine while-Schleife auswählen

6068
UsersUser

Es gibt ein Bash-Skript, das Dateien "magisch" ™ macht, die auf eine sqlite-Datenbank verwiesen werden, und nach "magisch" ™ sollte die Datenbank aktualisiert werden. Hier ist der vereinfachte Code

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 

Alles funktioniert, die sqlite-Datenbank wird Zeile für Zeile gelesen und ich könnte die referenzierten Dateien "magisch" machen, aber ich kann die Zeile in der Datenbank nicht aktualisieren - Ich habe einen Fehler:

Fehler: Datenbank ist gesperrt

Weiß jemand, wie ich eine Datenbank aktualisieren könnte, während ich eine Datenbank lese? Oder gibt es eine andere Lösung, wie ich das tun könnte?

1

2 Antworten auf die Frage

2
Matija Nalis

Wenn Sie nicht in eine echte SQL-Datenbank wechseln möchten und das Ergebnis vorübergehend nicht gespeichert werden kann, müssen Sie sicherstellen, dass Sie nicht gleichzeitig SELECT und UPDATE in derselben Tabelle ausführen.

Siehe die LIMIT- Direktive für SELECT.

so würden Sie so etwas tun:

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 

Dies würde dazu führen, dass SELECT immer nur ein Ergebnis und ein Ergebnis zurückgibt, das Sie dann bearbeiten und UPDATE ausführen und SELECT erneut ausführen würden, um das nächste Ergebnis zu erhalten (da sich STATUS geändert hat, würde SELECT den nächsten Wert erhalten, nicht den alten, da er nicht mehr mit "N" übereinstimmt.) )

oder vielleicht können Sie "etwas Magie (tm)" über SQL anstelle einer Shell ausführen, um die gesamte Arbeit in die SQL-Engine zu verlagern ...

Du hast recht. Mittlerweile habe ich eine andere Lösung mit zwei SQL-Abfragen gefunden (eine zum Setzen aller Selects in einem Bash-Array, eine andere zum Setzen von Variablen), aber Ihre Lösung ist einfacher und mit geringeren Ressourcen (ich denke) .a UsersUser vor 10 Jahren 0
1
choroba

Sie müssen in zwei Schritten vorgehen. Speichern Sie entweder das Ergebnis der ersten Abfrage in eine temporäre Datei (oder Variable) und verarbeiten Sie es dann. oder sammeln Sie die Aktualisierungsanweisungen in einer temporären Datei oder Variable und führen Sie sie aus, nachdem die Auswahl abgeschlossen ist.

Nun, das Problem ist: Dies ist eine riesige Datenbank, sodass ich das Ergebnis nicht als Datei oder als Variable speichern konnte, um alle Ergebnisse abzufangen. Und ich kann es nicht in zwei Schritte unterteilen, weil ich eine Schleife benötige, die alle Ergebnisse erfasst (oder ich wusste nicht, ob ich alle Zeilen der Datenbank einfangen könnte). UsersUser vor 10 Jahren 0
@UsersUser: Verwenden Sie dann eine echte Datenbank. choroba vor 10 Jahren 0
Ja, eine echte Datenbank wäre mit mehr Optionen einfacher, erfordert aber auch die Installation eines Datenbankservers, den ich nicht auf meinem Desktop-Computer haben möchte. UsersUser vor 10 Jahren 0