2010-04-10 27 views
11

Mam aplikację Flex/Air, nad którą pracowałem, wykorzystuje lokalną bazę danych sqlite, która jest tworzona przy początkowym uruchomieniu aplikacji.DODAJ KOLUMNĘ do sqlite db JESZCZE NIE ISTNIEJ - flex/air sqlite?

Dodałem niektóre funkcje do aplikacji i musiałem dodać nowe pole do jednej z tabel bazy danych. Moje pytania brzmią, w jaki sposób uzyskać wniosek o utworzenie jednego nowego pola, które znajduje się w tabeli, która już istnieje?

jest to linia, która tworzy tabelę

stmt.text = "CREATE TABLE IF NOT EXISTS tbl_status ("+"status_id INTEGER PRIMARY KEY AUTOINCREMENT,"+" status_status TEXT)"; 

A teraz chciałbym dodać pole status_default.

dziękuję!

Dzięki - MPelletier

mam dodać kod, który podałeś i to nie dodać pole, ale teraz następnym razem ponownie uruchomić aplikację pojawia się błąd - „status_default” już istnieje.

W jaki sposób mogę dodać oświadczenie IF NOT EXISTS do podanej linii?

+0

Jakiś powód, dla którego nie sprawdzono składni SQLite SQL na stronie http://www.sqlite.org? Składnia polecenia ALTER TABLE do dodania nowej kolumny nie ma żadnych modyfikatorów typu IF NOT EXISTS, co oznacza, że ​​będziesz musiał tylko obsłużyć wyjątek/błąd we własnym kodzie. –

+0

Adam, zaktualizowałem swoją odpowiedź. Patrz poniżej. – MPelletier

Odpowiedz

31
ALTER TABLE tbl_status ADD COLUMN status_default TEXT; 

http://www.sqlite.org/lang_altertable.html

Mając na uwadze powyższe, dodając kolumny w SQLite jest ograniczona. Nie możesz dodać kolumny w dowolnym miejscu, ale po ostatniej kolumnie w tabeli.

Jeśli chodzi o sprawdzanie, czy kolumna już istnieje, PRAGMA table_info(tbl_status); zwróci tabelę z listą różnych kolumn w tabeli.

ADD ON:

Używam strategii w projektowaniu baz danych, który umożliwia mi rozróżnić, jakie modyfikacje są wymagane. W tym celu potrzebna jest nowa tabela (pod numerem DBInfo) z jednym polem (Integer, nazwij go SchemaVersion). Alternatywnie istnieje również wartość wewnętrzna w SQLite o nazwie user_version, którą można ustawić za pomocą komendy PRAGMA. Twój kod może podczas uruchamiania programu sprawdzić numer wersji schematu i odpowiednio zastosować zmiany, jedną wersję na raz.

Załóżmy funkcję o nazwie UpdateDBSchema(). Ta funkcja sprawdzi wersję schematu bazy danych, nie będzie obsługiwać DBInfo i określi, że baza danych jest w wersji 0. Reszta tej funkcji może być po prostu dużym przełącznikiem z różnymi wersjami, zagnieżdżonymi w pętli (lub innej dostępnej strukturze do wybranej platformy).

Więc dla tej pierwszej wersji, mają UpgradeDBVersion0To1() funkcję, która będzie tworzyć tę nową tabelę (DBInfo), dodać pole status_default i ustaw SchemaVersion do 1. W kodzie dodać stałą wskazującą najnowszą wersję schematu, powiedz LATEST_DB_VERSION i ustaw go na 1. W ten sposób twój kod i baza danych mają wersję schematu i wiesz, że musisz je zsynchronizować, jeśli nie są równe.

Jeśli chcesz wprowadzić kolejną zmianę w swoim schemacie, ustaw stałą na LATEST_DB_VERSION na 2 i wykonaj nową funkcję UpgradeDBVersion1To2(), która wykona wymagane zmiany.

W ten sposób Twój program może być łatwo przenoszony, może łączyć się i aktualizować starą bazę danych itp.

+0

Użytkownik może w każdej chwili ustawić i zmienić wartość domyślną, więc nie mogę nadać mu ustawionej wartości. – Adam

+0

Jeszcze raz dziękuję MPelletier, która naprawdę mi pomogła! – Adam

+0

W ten sposób zaimplementowano RoundhousE. https://github.com/chucknorris/roundhouse/wiki – Clay

0

I rozwiązać podobny problem z użyciem odpowiedź na to pytanie: ALTER TABLE ADD COLUMN IF NOT EXISTS in SQLite

korzystać z wbudowanych w parametrze user_version aby śledzić aktualizacje. Ustawić go za pomocą:

PRAGMA user_version = 1 

i pobrać go za pomocą

PRAGMA user_version 

Więc w zasadzie pobierać user_version (jest domyślnie 0), sprawdź, czy jest to 0. Jeśli tak, należy przeprowadzić aktualizacje i ustawić ją na 1. Jeśli będziesz mieć więcej aktualizacji w przyszłości, sprawdź, czy jest to 1, wykonaj aktualizacje i ustaw 0. I tak dalej ...

2

Wiem, że to stare pytanie ... jednak.

Uderzyłem w ten konkretny problem w implementacji SQLite w środowisku Adobe AIR. Pomyślałem, że będzie można użyć polecenia PRAGMA do rozwiązania, ale ponieważ implementacja Adobe AIR nie obsługuje polecenia PRAGMA, potrzebujemy alternatywy.

Co zrobiłem, że myślałem, że byłoby warto dzielić tutaj, jest to:

var sql:SQLStatement = new SQLStatement(); 
sql.sqlConnection = pp_db.dbConn; 
sql.text = "SELECT NewField FROM TheTable"; 
sql.addEventListener(SQLEvent.RESULT, function(evt:SQLEvent):void { 
}); 

sql.addEventListener(SQLErrorEvent.ERROR, function(err:SQLErrorEvent):void { 
    var sql:SQLStatement = new SQLStatement(); 
    sql.sqlConnection = pp_db.dbConn; 
    sql.text = "ALTER TABLE TheTable ADD COLUMN NewField NUMERIC;"; 
    sql.execute(); 
    sql.addEventListener(SQLEvent.RESULT, function (evt:SQLEvent):void { 
    }); 
}); 
sql.execute(); 

Mam nadzieję, że ktoś pomoże.

+0

Pomocna w przypadku, gdy pragma nie jest dostępna, ale rozwiązanie MPelletiera jest tym, co powinien zrobić każdy programista w celu obsługi wersji bazy danych i uaktualnień –

+0

PRAGMA NIE jest dostępna w scenariuszu PO, stąd umieszczenie go jako właściwego rozwiązania dla tego konkretnego scenariusza. – stevesweets

0

W niektórych przypadkach wykonuję polecenie i otrzymuję wyjątek dla "duplikatu kolumny". To tylko szybkie rozwiązanie, a nie idealne.