Как проверить в SQLite, существует ли таблица?

Как я надежно, проверьте в SQLite, существует ли конкретная таблица пользователей?

Я не прошу ненадежных способов, таких как проверка, если "select *" на таблице вернул ошибку или нет (это даже хорошая идея?).

причина такой:

в моей программе мне нужно создать, а затем заполнить некоторые таблицы, если они еще не существуют.

Если они уже существуют, мне нужно обновить некоторые таблицы.

должен ли я взять какой - то другой путь, чтобы сигнализировать, что таблицы, о которых идет речь, уже созданы-скажем, например, путем создания/установки/установки определенного флага в моем файле инициализации/настроек программы на диске или что-то еще?

или мой подход имеет смысл?

18 ответов


я пропустил эту запись.

в любом случае, для дальнейшего использования полный запрос:

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

здесь {table_name} - имя таблицы для проверки.

раздел документации для справки:Формат Файла Базы Данных. 2.6. Хранение схемы базы данных SQL


Если вы используете SQLite версии 3.3+ вы можете легко создать таблицу с:

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

таким же образом вы можете удалить таблицу, только если она существует, используя:

drop table if exists TableName

вариант будет использовать SELECT COUNT (*) вместо SELECT NAME, т. е.

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

это вернет 0, если таблица не существует, 1, если это так. Это, вероятно, полезно в вашем программировании, так как численный результат быстрее / проще в обработке. Ниже показано, как это можно сделать в Android с помощью SQLiteDatabase, Cursor, rawQuery с параметрами.

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;
}

вы можете попробовать:

SELECT name FROM sqlite_master WHERE name='table_name'

Если вы получаете ошибку "таблица уже существует", внесите изменения в строку SQL, как показано ниже:

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

таким образом, вы можете избежать исключения.


посмотреть этой:

SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;

имена таблиц SQLite нечувствительны к регистру, но сравнение по умолчанию чувствительно к регистру. Чтобы сделать эту работу правильно во всех случаях, вам нужно добавить COLLATE NOCASE.

SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE

использование:

PRAGMA table_info(your_table_name)

Если результирующая таблица пуста, то your_table_name не существует.

документы:

схема PRAGMA.table_info(таблица-имя);

эта ПРАГМА возвращает одну строку для каждого столбца в именованной таблице. Столбцы в результирующем наборе включают имя столбца, тип данных, может ли столбец иметь значение NULL, и значение по умолчанию для столбца. Столбец "pk" в результирующем наборе равен нулю для столбцов, которые не являются частью и является индексом столбца в первичном ключе для столбцов, которые являются частью первичного ключа.

таблица с именем в прагме table_info также может быть представлением.

пример:

cid|name|type|notnull|dflt_value|pk
0|id|INTEGER|0||1
1|json|JSON|0||0
2|name|TEXT|0||0

Если вы используете FMDB по, Я думаю, вы можете просто импорт FMDatabaseAdditions и используйте функцию bool:

[yourfmdbDatabase tableExists:tableName].

следующий код возвращает 1, если таблица существует или 0, если таблица не существует.

SELECT CASE WHEN tbl_name = "name" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "name" AND type = "table"

обратите внимание, что для проверки наличия таблицы в базе данных TEMP необходимо использовать sqlite_temp_master вместо sqlite_master:

SELECT name FROM sqlite_temp_master WHERE type='table' AND name='table_name';

вот функция, которую я использовал:

учитывая объект SQLDatabase = db

public boolean exists(String table) {
    try {
         db.query("SELECT * FROM " + table);
         return true;
    } catch (SQLException e) {
         return false;
    }
}

используйте этот код:

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

если возвращаемое число массивов равно 1, это означает, что таблица существует. Иначе его не существует.


использовать

SELECT 1 FROM table LIMIT 1;

для предотвращения чтения всех записей.


использование простого запроса SELECT является, на мой взгляд, довольно надежным. Больше всего он может проверить существование таблицы во многих различных типах баз данных (SQLite / MySQL).

SELECT 1 FROM table;

имеет смысл, когда вы можете использовать другой надежный механизм для определения успеха запроса (например, вы запрашиваете базу данных через QSqlQuery в Qt).


вы можете написать следующий запрос, чтобы проверить существование таблицы.

SELECT name FROM sqlite_master WHERE name='table_name'

здесь "table_name" - это имя таблицы, которую вы создали. Например

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

и

  SELECT name FROM sqlite_master WHERE name='country'

Это мой код для 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");
    }
});

и еще одна:

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, '').split(','); ///// RegEx
                for (i in columnParts) {
                    if (typeof columnParts[i] === 'string')
                        columnNames.push(columnParts[i].split(" ")[0]);
                };
                callback(columnNames);
            }
            else callback(columnNames);
        });
    });
}

Я думал, что вложу свои 2 цента в эту дискуссию, даже если она довольно старая.. Этот запрос возвращает скаляр 1, если таблица существует и 0 в противном случае.

select 
    case when exists 
        (select 1 from sqlite_master WHERE type='table' and name = 'your_table') 
        then 1 
        else 0 
    end as TableExists