Проверьте, существует ли столбец в SQLite
Мне нужно проверить, существует ли столбец, и если он не существует, добавьте его. Из моего исследования видно, что sqlite не поддерживает операторы IF, и вместо них следует использовать оператор case.
Вот что у меня так далеко:
SELECT CASE WHEN exists(select * from qaqc.columns where Name = "arg" and Object_ID = Object_ID("QAQC_Tasks")) = 0 THEN ALTER TABLE QAQC_Tasks ADD arg INT DEFAULT(0);
Но я получаю ошибку: Рядом с "ALTER": синтаксическая ошибка.
Есть идеи?
18 ответов
Вы не можете использовать ALTER TABLE with
дело.
Вы ищете для получения имен столбцов для таблицы::-
PRAGMA table_info(table-name);
Проверьте этот учебник на PRAGMA
Эта прагма возвращает одну строку для каждого столбца в именованной таблице. Столбцы в наборе результатов включают имя столбца, тип данных, может ли столбец иметь значение NULL и значение по умолчанию для столбца. Столбец "pk" в наборе результатов равен нулю для столбцов, которые не являются частью первичного ключа, и является индексом столбца в первичном ключе для столбцов, которые являются частью первичного ключа.
Хотя это старый вопрос, я нашел в функции PRAGMA более простое решение:
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('tablename') WHERE name='column_name'
Если результат больше нуля, столбец существует. Простой и однострочный запрос
Хитрость заключается в использовании
pragma_table_info('tablename')
вместо
PRAGMA table_info(tablename)
Изменить: Обратите внимание, что, как сообщается в функциях PRAGMA:
Эта функция является экспериментальной и может быть изменена. Дальнейшая документация станет доступной, если и когда будут официально поддерживаться табличные функции для функции PRAGMA.
Табличные функции для функции PRAGMA были добавлены в SQLite версии 3.16.0 (2017-01-02). Предыдущие версии SQLite не могли использовать эту функцию.
// This method will check if column exists in your table
public boolean isFieldExist(String tableName, String fieldName)
{
boolean isExist = false;
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("PRAGMA table_info("+tableName+")",null);
res.moveToFirst();
do {
String currentColumn = res.getString(1);
if (currentColumn.equals(fieldName)) {
isExist = true;
}
} while (res.moveToNext());
return isExist;
}
Я применил это решение:
public boolean isFieldExist(SQLiteDatabase db, String tableName, String fieldName)
{
boolean isExist = false;
Cursor res = null;
try {
res = db.rawQuery("Select * from "+ tableName +" limit 1", null);
int colIndex = res.getColumnIndex(fieldName);
if (colIndex!=-1){
isExist = true;
}
} catch (Exception e) {
} finally {
try { if (res !=null){ res.close(); } } catch (Exception e1) {}
}
return isExist;
}
Это вариант кода от Панкаджа Джангида.
Вы не указали язык, поэтому, предполагая, что это не чистый SQL, вы можете проверить наличие ошибок при запросе столбцов:
SELECT col FROM table;
если вы получаете сообщение об ошибке и знаете, что столбца нет (при условии, что вы знаете, что таблица существует, в любом случае у вас есть "ЕСЛИ НЕ СУЩЕСТВУЕТ" для этого), в противном случае столбец существует, и затем вы можете соответствующим образом изменить таблицу.
SELECT EXISTS (SELECT * FROM sqlite_master WHERE tbl_name = 'TableName' AND sql LIKE '%ColumnName%');
... помните об условии LIKE, которое несовершенно, но оно работает для меня, так как все мои столбцы имеют очень уникальные имена..
Используйте с try, catch и, наконец, для любых выполнений rawQuery() для лучших практик. И следующий код даст вам результат.
public boolean isColumnExist(String tableName, String columnName)
{
boolean isExist = false;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = null;
try {
cursor = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);
if (cursor.moveToFirst()) {
do {
String currentColumn = cursor.getString(cursor.getColumnIndex("name"));
if (currentColumn.equals(columnName)) {
isExist = true;
}
} while (cursor.moveToNext());
}
}catch (Exception ex)
{
Log.e(TAG, "isColumnExist: "+ex.getMessage(),ex );
}
finally {
if (cursor != null)
cursor.close();
db.close();
}
return isExist;
}
Странный способ проверить существующий столбец
public static bool SqliteColumnExists(this SQLiteCommand cmd, string table, string column)
{
lock (cmd.Connection)
{
// make sure table exists
cmd.CommandText = string.Format("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = '{0}'", table);
var reader = cmd.ExecuteReader();
if (reader.Read())
{
//does column exists?
bool hascol = reader.GetString(0).Contains(String.Format("\"{0}\"", column));
reader.Close();
return hascol;
}
reader.Close();
return false;
}
}
Чтобы получить имена столбцов для таблицы:
PRAGMA table_info (tableName);
Чтобы получить индексированные столбцы:
PRAGMA index_info (indexName);
Обновите DATABASE_VERSION, чтобы вызывать функцию onUpgrade, тогда, если Столбец уже существует, тогда ничего не произойдет, если нет, то он добавит новый столбец.
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (!isColumnExists(db, "YourTableName", "YourColumnName")) {
try {
String sql = "ALTER TABLE " + "YourTableName" + " ADD COLUMN " + "YourColumnName" + "TEXT";
db.execSQL(sql);
} catch (Exception localException) {
db.close();
}
}
}
}
public static boolean isColumnExists(SQLiteDatabase sqliteDatabase,
String tableName,
String columnToFind) {
Cursor cursor = null;
try {
cursor = sqliteDatabase.rawQuery(
"PRAGMA table_info(" + tableName + ")",
null
);
int nameColumnIndex = cursor.getColumnIndexOrThrow("name");
while (cursor.moveToNext()) {
String name = cursor.getString(nameColumnIndex);
if (name.equals(columnToFind)) {
return true;
}
}
return false;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
я использовал следующие
SELECT
оператор с SQLite 3.13.0
SELECT INSTR(sql, '<column_name>') FROM sqlite_master WHERE type='table' AND name='<table_name>';
Возвращает 0 (ноль), если столбец
<column_name>
не существует в таблице
<table_name>
.
Я обновил функцию друга... проверено и работает сейчас
public boolean isFieldExist(String tableName, String fieldName)
{
boolean isExist = false;
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);
if (res.moveToFirst()) {
do {
int value = res.getColumnIndex("name");
if(value != -1 && res.getString(value).equals(fieldName))
{
isExist = true;
}
// Add book to books
} while (res.moveToNext());
}
return isExist;
}
Мне очень жаль, что я опоздал. Размещение в намерении может быть полезным в чьем-то случае.
Я попытался извлечь столбец из базы данных. Если он возвращает строку, он содержит этот столбец, иначе нет...
-(BOOL)columnExists {
BOOL columnExists = NO;
//Retrieve the values of database
const char *dbpath = [[self DatabasePath] UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){
NSString *querySQL = [NSString stringWithFormat:@"SELECT lol_10 FROM EmployeeInfo"];
const char *query_stmt = [querySQL UTF8String];
int rc = sqlite3_prepare_v2(database ,query_stmt , -1, &statement, NULL);
if (rc == SQLITE_OK){
while (sqlite3_step(statement) == SQLITE_ROW){
//Column exists
columnExists = YES;
break;
}
sqlite3_finalize(statement);
}else{
//Something went wrong.
}
sqlite3_close(database);
}
return columnExists;
}
public static bool columExsist(string table, string column)
{
string dbPath = Path.Combine(Util.ApplicationDirectory, "LocalStorage.db");
connection = new SqliteConnection("Data Source=" + dbPath);
connection.Open();
DataTable ColsTable = connection.GetSchema("Columns");
connection.Close();
var data = ColsTable.Select(string.Format("COLUMN_NAME='{1}' AND TABLE_NAME='{0}1'", table, column));
return data.Length == 1;
}
Похожий на IF
в SQLite, CASE
в SQLite это выражение. Вы не можете использовать ALTER TABLE
с этим. Смотрите: http://www.sqlite.org/lang_expr.html
Некоторые из этих примеров не сработали для меня. Я пытаюсь проверить, содержит ли моя таблица столбец или нет.
Я использую этот фрагмент:
public boolean tableHasColumn(SQLiteDatabase db, String tableName, String columnName) {
boolean isExist = false;
Cursor cursor = db.rawQuery("PRAGMA table_info("+tableName+")",null);
int cursorCount = cursor.getCount();
for (int i = 1; i < cursorCount; i++ ) {
cursor.moveToPosition(i);
String storedSqlColumnName = cursor.getString(cursor.getColumnIndex("name"));
if (columnName.equals(storedSqlColumnName)) {
isExist = true;
}
}
return isExist;
}
Приведенные выше примеры запрашивают таблицу прагмы, которая является таблицей метаданных, а не фактическими данными, каждый столбец указывает имена, тип и некоторые другие элементы столбцов таблицы. Таким образом, фактические имена столбцов находятся в строках.
Надеюсь, что это поможет кому-то еще.
Ответ Панкаджа Джангида близок, но не совсем корректен. Вот это с исправлениями:
public boolean isColumnExists(SQLiteDatabase sqliteDatabase,
String tableName,
String columnToFind) {
Cursor cursor = null;
try {
cursor = sqLiteDatabase.rawQuery(
"PRAGMA table_info(" + tableName + ")",
null
);
int nameColumnIndex = cursor.getColumnIndexOrThrow("name");
while (cursor.moveToNext()) {
String name = cursor.getString(nameColumnIndex);
if (name.equals(columnToFind)) {
return true;
}
}
return false;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
SELECT INSTR(Lower(sql), " exceptionclass ") FROM sqlite_master WHERE type="table" AND Lower(name)="bugsgroup";