Bir süre döngüsü içine seçim yaparken sqlite veritabanını güncelleyin


4

Bir sqlite veritabanına referans verilecek dosyalara "biraz sihir" ™ yapacak bir bash betiği vardır ve "biraz sihir" yaptıktan sonra veritabanının güncellenmesi gerekir. İşte basitleştirilmiş kod

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

Her şey işe yarıyor, sqlite veritabanı satır satır okunacak ve başvurulan dosyalara "biraz sihir" ™ yapabildim, fakat veritabanındaki satırı güncelleyemiyorum - bir hatayla karşılaştım:

Hata: veritabanı kilitli

Veritabanını okurken bir veritabanını nasıl güncelleyebileceğimi bilen var mı? Yoksa bunu nasıl yapabileceğim başka bir çözüm var mı?

Yanıtlar:


3

gerçek bir SQL veritabanına geçmek istemiyorsanız ve sonucu geçici olarak saklamak mümkün değilse, aynı tabloda aynı anda SELECT ve UPDATE çalıştırmadığınızdan emin olmanız gerekir.

SELECT için LIMIT yönergesine bakınız .

yani şöyle bir şey yapardın:

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

Bu SELECT'i her zaman sadece bir sonuç döndürür ve bitirir, o zaman işler ve GÜNCELLEME yaparsınız ve bir sonraki sonucu almak için SELECT'i tekrar çalıştırırsınız (DURUM değiştiğinde, SELECT bir sonraki değeri elde eder, eski olanı artık "N" ile eşleşmez. )

ya da belki bir kabuk yerine SQL ile "biraz sihir (tm)" yapabilirdiniz, böylece tüm işleri SQL motoruna yükleyebilirsiniz ...


Haklısın. Bu arada iki sql sorguyla (bir bash dizisindeki tüm seçimleri ayarlamak için bir tane, değişkenleri ayarlamak için bir tane daha) başka bir çözüm buldum ama çözümünüz daha kolay ve daha düşük kaynaklarla (sanırım) .a
UsersUser

1
Bu benim için çalıştı. Limitimi çok daha büyük bir sayıya (1000) belirledim ve gruplar halinde çalıştım, böylece sorguyu tekrar çalıştırmayacak ya da her bir kayıt güncellemesini taahhüt etmeyecektim. Çok büyük bir veri setim vardı, bu yüzden önemliydi. İlk başta her yinelemede sorguyu yeniden çalıştırma konusunda biraz endişeliydim, ancak bu sonuçta gözle görülür bir performans sorunu yaratmadı.
Tristan,

1

İki adımda ilerlemelisin. Her iki durumda da, ilk sorgunun sonucunu geçici bir dosyaya (veya değişkene) saklayın ve ardından işleyin; veya, güncelleme ifadelerini geçici bir dosyada veya değişkende toplayın ve seçim bittikten sonra yürütün.


Sorun şu: bu çok büyük bir veri tabanı, bu yüzden sonucu tüm sonuçları yakalamak için bir dosya ya da değişken olarak saklayamadım. Ve bunu iki adıma ayıramıyorum çünkü tüm sonuçları yakalayacak bir döngüye ihtiyacım var (veya veritabanının tüm satırlarını yakalayabileceğimi bilmiyordum).
UsersUser

@ KullanıcıKullanıcı: Sonra gerçek bir veritabanı kullanın.
choroba

Evet, gerçek bir veritabanı daha fazla seçenekle daha kolay olurdu, fakat aynı zamanda masaüstü bilgisayarımda istemediğim bir veritabanı sunucusu kurulumuna da ihtiyacı var.
UsersUser
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.