Jak Sprawdzić w SQLite czy istnieje tabela?

Jak, } rzetelnie Sprawdzić w SQLite, czy istnieje konkretna tabela użytkowników?

Nie proszę o nierzetelne sposoby, takie jak sprawdzenie, czy "select *" na stole zwrócił błąd, czy nie (czy to w ogóle dobry pomysł?).

Powód jest taki:

W moim programie, muszę utworzyć, a następnie wypełnić kilka tabel, jeśli jeszcze nie istnieją.

Jeśli już istnieją, muszę zaktualizować niektóre tabele.

Czy powinienem wybrać inną drogę zamiast do sygnał, że dane tabele zostały już utworzone-np. poprzez utworzenie / umieszczenie / ustawienie pewnej flagi w moim pliku inicjalizacji/ustawień programu na dysku czy coś?

Czy moje podejście ma sens?

 771
Author: Peter Mortensen, 2009-10-21

18 answers

Przegapiłem ten wpis FAQ.

W każdym razie, dla przyszłego odniesienia, pełne zapytanie to:

SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}';

Gdzie {table_name} jest nazwą tabeli do sprawdzenia.

Sekcja dokumentacji dla odniesienia: format pliku bazy danych. 2.6. Przechowywanie schematu bazy danych SQL

 876
Author: PoorLuzer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-19 04:16:41

Jeśli używasz SQLite w wersji 3.3+ możesz łatwo utworzyć tabelę za pomocą:

create table if not exists TableName (col1 typ1, ..., colN typN)

W ten sam sposób można usunąć tabelę tylko wtedy, gdy istnieje, używając:

drop table if exists TableName
 485
Author: arthur johnston,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-31 02:50:56

Odmianą byłoby użycie select COUNT (*) zamiast SELECT NAME, tzn.

SELECT count(*) FROM sqlite_master WHERE type='table' AND name='table_name';

Zwróci 0, jeśli tabela nie istnieje, 1, jeśli istnieje. Jest to prawdopodobnie przydatne w programowaniu, ponieważ wynik liczbowy jest szybszy / łatwiejszy do przetworzenia. Poniżej przedstawiono, jak można to zrobić w Androidzie za pomocą SQLiteDatabase, Cursor, rawQuery z parametrami.

boolean tableExists(SQLiteDatabase db, String tableName)
{
    if (tableName == null || db == null || !db.isOpen())
    {
        return false;
    }
    Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM sqlite_master WHERE type = ? AND name = ?", new String[] {"table", tableName});
    if (!cursor.moveToFirst())
    {
        cursor.close();
        return false;
    }
    int count = cursor.getInt(0);
    cursor.close();
    return count > 0;
}
 156
Author: Stephen Quan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-06 00:32:56

Możesz spróbować:

SELECT name FROM sqlite_master WHERE name='table_name'
 39
Author: Galwegian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-21 14:25:51

Jeśli pojawi się błąd "Tabela już istnieje", wprowadź zmiany w łańcuchu SQL jak poniżej:

CREATE table IF NOT EXISTS table_name (para1,para2);

W ten sposób można uniknąć WYJĄTKÓW.

 34
Author: Rakesh Chaudhari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 17:05:47

Zobacz to :

SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
 27
Author: Anton Gogolev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-21 14:25:32

Nazwy tabel SQLite są niewrażliwe na wielkość liter, ale porównanie domyślnie uwzględnia wielkość liter. Aby to działało poprawnie we wszystkich przypadkach należy dodać COLLATE NOCASE.

SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE
 27
Author: Brice M. Dempsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-22 18:07:00

Użycie:

PRAGMA table_info(your_table_name)

Jeśli tabela wynikowa jest pusta, to your_table_name nie istnieje.

Dokumentacja:

Schemat PRAGMA.table_info (table-name);

Ta pragma zwraca jeden wiersz dla każdej kolumny w nazwanej tabeli. Kolumny w zestawie wynikowym zawierają nazwę kolumny, typ danych, czy kolumna może mieć wartość NULL oraz domyślną wartość dla kolumny. Kolumna " pk " w zestawie wynikowym jest równa zero dla kolumn, które nie są częścią klucza podstawowego i jest indeksem kolumny w kluczu głównym dla kolumn, które są częścią klucza głównego.

Tabela o nazwie table_info pragma może być również widokiem.

Przykładowe wyjście:

cid|name|type|notnull|dflt_value|pk
0|id|INTEGER|0||1
1|json|JSON|0||0
2|name|TEXT|0||0
 27
Author: Diego Vélez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-01 15:50:16

Jeśli używasz fmdb , myślę, że możesz po prostu zaimportować fmdatabaseadditions i użyć funkcji bool:

[yourfmdbDatabase tableExists:tableName].
 22
Author: user655489,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-26 12:10:18

Następujący kod zwraca 1, jeśli tabela istnieje lub 0, jeśli tabela nie istnieje.

SELECT CASE WHEN tbl_name = "name" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "name" AND type = "table"
 13
Author: pacheco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 16:59:00

Zauważ, że aby sprawdzić, czy tabela istnieje w bazie danych TEMP, musisz użyć sqlite_temp_master zamiast sqlite_master:

SELECT name FROM sqlite_temp_master WHERE type='table' AND name='table_name';
 10
Author: Scott Deerwester,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 15:49:33

Oto funkcja, której użyłem:

Podano obiekt SQLDatabase = db

public boolean exists(String table) {
    try {
         db.query("SELECT * FROM " + table);
         return true;
    } catch (SQLException e) {
         return false;
    }
}
 6
Author: DroidGrailer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-11 17:56:33

Użyj tego kodu:

SELECT name FROM sqlite_master WHERE type='table' AND name='yourTableName';

Jeśli zwracana liczba tablic jest równa 1, oznacza to, że tabela istnieje. W przeciwnym razie nie istnieje.

 6
Author: asmad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 17:01:38

Użyj

SELECT 1 FROM table LIMIT 1;

Aby zapobiec odczytywaniu wszystkich rekordów.

 3
Author: Franz Fahrenkrog Petermann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-28 17:27:34

Użycie prostego zapytania SELECT jest - moim zdaniem-dość wiarygodne. Przede wszystkim może sprawdzać istnienie tabel w wielu różnych typach baz danych (SQLite / MySQL).

SELECT 1 FROM table;

Ma to sens, gdy możesz użyć innego niezawodnego mechanizmu do określenia, czy zapytanie się powiodło (na przykład, odpytywasz bazę danych za pomocą QSqlQuery w Qt ).

 1
Author: Grz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 17:00:32

Możesz napisać następujące zapytanie, aby sprawdzić istnienie tabeli.

SELECT name FROM sqlite_master WHERE name='table_name'

Tutaj 'table_name' jest nazwą Twojej tabeli, którą utworzyłeś. Na przykład

 CREATE TABLE IF NOT EXISTS country(country_id INTEGER PRIMARY KEY AUTOINCREMENT, country_code TEXT, country_name TEXT)"

I sprawdź

  SELECT name FROM sqlite_master WHERE name='country'
 1
Author: Anantha krishnan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-02 10:14:55

To jest mój kod do SQLite Cordova:

get_columnNames('LastUpdate', function (data) {
    if (data.length > 0) { // In data you also have columnNames
        console.log("Table full");
    }
    else {
        console.log("Table empty");
    }
});

I drugi:

function get_columnNames(tableName, callback) {
    myDb.transaction(function (transaction) {
        var query_exec = "SELECT name, sql FROM sqlite_master WHERE type='table' AND name ='" + tableName + "'";
        transaction.executeSql(query_exec, [], function (tx, results) {
            var columnNames = [];
            var len = results.rows.length;
            if (len>0){
                var columnParts = results.rows.item(0).sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').split(','); ///// RegEx
                for (i in columnParts) {
                    if (typeof columnParts[i] === 'string')
                        columnNames.push(columnParts[i].split(" ")[0]);
                };
                callback(columnNames);
            }
            else callback(columnNames);
        });
    });
}
 0
Author: Zappescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 17:07:36

Pomyślałem, że poświęcę swoje 2 centy na tę dyskusję, nawet jeśli jest dość stara.. To zapytanie zwraca Skalar 1, jeśli tabela istnieje i 0 w przeciwnym razie.

select 
    case when exists 
        (select 1 from sqlite_master WHERE type='table' and name = 'your_table') 
        then 1 
        else 0 
    end as TableExists
 0
Author: Piotr Rodak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-10 22:13:28